7d7ba731c432325f1b3c235402a5af54b23e1ec7
chmalee
  Fri Nov 3 14:59:07 2023 -0700
Make user clicks into an input or select or contextmenu make tooltips go away. Also decrease fudgeFactor on mousemove so tooltips are a little more senstitive and turn off faster, refs Max email

diff --git src/hg/js/utils.js src/hg/js/utils.js
index 660f173..008cfd6 100644
--- src/hg/js/utils.js
+++ src/hg/js/utils.js
@@ -3920,69 +3920,69 @@
 // signal handler for when mousemove has gone far enough away from the pop up
 // we can't use removeEventListener because the function call is hard to keep
 // track of because of a bounded this keyword
 let mousemoveController;
 // The div that moves around the users screen with the visible mouseover text
 var mouseoverContainer;
 
 function hideMouseoverText(ele) {
     /* Actually hides the tooltip text */
     let tooltipTarget = ele;
     tooltipTarget.classList.remove("isShown");
     tooltipTarget.style.opacity = "0";
     tooltipTarget.style.visibility = "hidden";
 }
 
-function mouseIsOverPopup(ev, ele, fudgeFactor=45) {
+function mouseIsOverPopup(ev, ele, fudgeFactor=25) {
     /* Is the mouse positioned over the popup? */
     let targetBox = ele.getBoundingClientRect();
     let mouseX = ev.clientX;
     let mouseY = ev.clientY;
     if ( (mouseX >= (targetBox.left - fudgeFactor) && mouseX <= (targetBox.right + fudgeFactor) &&
             mouseY >= (targetBox.top - fudgeFactor) && mouseY <= (targetBox.bottom + fudgeFactor)) ) {
         return true;
     }
     return false;
 }
 
-function mouseIsOverItem(ev, ele, fudgeFactor=45) {
+function mouseIsOverItem(ev, ele, fudgeFactor=25) {
     /* Is the mouse positioned over the item that triggered the popup? */
     let origName = ele.getAttribute("origItemMouseoverId");
     let origTargetBox = boundingRect($("[mouseoverid='"+origName+"']")[0]);
     let mouseX = ev.clientX;
     let mouseY = ev.clientY;
     if ( (mouseX >= (origTargetBox.left - fudgeFactor) && mouseX <= (origTargetBox.right + fudgeFactor) &&
             mouseY >= (origTargetBox.top - fudgeFactor) && mouseY <= (origTargetBox.bottom + fudgeFactor)) ) {
         return true;
     }
     return false;
 }
 
 function mousemoveTimerHelper(e) {
     /* user has moved the mouse and then stopped moving for long enough. */
     clearTimeout(mousemoveTimer);
     canShowNewMouseover = true;
     mousemoveTimer = undefined;
 }
 
 function mousemoveHelper(e) {
     /* Helper function for deciding whether to keep a tooltip visible upon a mousemove event */
     if (mousemoveTimer === undefined) {
         // if we are over another mouseable element we want to show that one instead
         // use this timer to do so
         let callback = mousemoveTimerHelper.bind(mouseoverContainer);
-        mousemoveTimer = setTimeout(callback, 250, e);
+        mousemoveTimer = setTimeout(callback, 500, e);
     }
 
     if (mousedNewItem && canShowNewMouseover && !mouseIsOverPopup(e, this, 0)) {
         // the !mouseIsOverPopup() check catches the corner case where the mouse
         // was moved slowly enough to the popup to set off the mousemoveTimer, but
         // is now over the pop up itself
         hideMouseoverText(this);
         mousemoveController.abort();
     } else {
         if (mouseIsOverPopup(e, this) || mouseIsOverItem(e, this)) {
             // the mouse is in the general area of the popup/item
             // the mouse needs to stop moving and then the flag will
             // get set by the mousemoveTimer
             canShowNewMouseover = false;
             return;
@@ -4102,30 +4102,83 @@
 }
 
 function titleTagToMouseover(mapEl) {
     /* for a given area tag, extract the title text into a div that can be positioned
     * like a standard tooltip mouseover next to the item */
     addMouseover(mapEl, mapEl.title);
 }
 
 function convertTitleTagsToMouseovers() {
     /* make all the title tags in the ideogram or main image have mouseovers */
     $("[name=ideoMap]>[title],#imgTbl [title]").each(function(i, a) {
         if (a.title !== undefined && a.title.length > 0) {
             titleTagToMouseover(a);
         }
     });
+    const inps = document.getElementsByTagName("input");
+    const sels = document.getElementsByTagName("select");
+    for (let inp of inps) {
+        if (!(inp.type == "hidden" || inp.type == "HIDDEN")) {
+            inp.addEventListener("focus", (ev) => {
+                hideMouseoverText(mouseoverContainer);
+                mousemoveController.abort();
+                canShowNewMouseover = false;
+            });
+            inp.addEventListener("blur", (evt) => {
+                canShowNewMouseover = true;
+            });
+        }
+    }
+    for (let sel of sels) {
+        sel.addEventListener("focus", (ev) => {
+            hideMouseoverText(mouseoverContainer);
+            mousemoveController.abort();
+            canShowNewMouseover = false;
+        });
+        sel.addEventListener("blur", (evt) => {
+            canShowNewMouseover = true;
+        });
+    }
+    let imgTbl = document.getElementById("imgTbl");
+    if (imgTbl) {
+        imgTbl.addEventListener("contextmenu", function(e) {
+            hideMouseoverText(mouseoverContainer);
+            mousemoveController.abort();
+            canShowNewMouseover = false;
+            // right-click menu doesn't capture focus so manually catch it
+            document.addEventListener("click", function(ev) {
+                // there is a race condition where the close happens after an inputs
+                // focus happens, which means mouseovers get re-enabled when the focus
+                // on the input should prevent them, catch that here:
+                if (!(document.activeElement.tagName === "INPUT" ||
+                        document.activeElement === "SELECT")) {
+                    canShowNewMouseover = true;
+                }
+            }, {once: true});
+            document.addEventListener("keyup", function(ev) {
+                if (ev.keyCode == 27) {
+                    // there is a race condition where the close happens after an inputs
+                    // focus happens, which means mouseovers get re-enabled when the focus
+                    // on the input should prevent them, catch that here:
+                    if (!(document.activeElement.tagName === "INPUT" ||
+                            document.activeElement === "SELECT")) {
+                        canShowNewMouseover = true;
+                    }
+                }
+            }, {once: true});
+        });
+    }
 }
 
 function tooltipNodesToMouseover() {
     /* For server side printed tooltip texts, make them work as pop ups.
      * Note this assumes two siblings nodes placed next to each other:
      *    <nodeName class="Tooltip">the text or element that is hoverable</nodename>
      *    <nodeName class="Tooltiptext'>the text/html of the popup itself
      * Please note that the Tooltiptext node can have any arbitrary html in it, like
      * line breaks or links*/
     $(".Tooltip").each(function(i, n) {
         tooltiptext = n.getAttribute("mouseoverText");
         if (tooltiptext !== null) {
             addMouseover(n, tooltiptext);
         }
     });