83ffc65b0574e8b3bfd7d191548ccde8651670b2
chmalee
  Tue Apr 2 11:28:22 2024 -0700
Fix tooltip bug, when the user is moving their mouse and triggers a new mouseover event, we need to clear the mousemove event that was checking if they were heading to the tooltip. By clearing this event we prevent the mousemoveTimerHelper function from running, which in this case is mistakenly re-triggering a mouseover event but on the wrong event coordinates, leading to tooltips that are a ways away from where they are supposed to be, refs Max email

diff --git src/hg/js/utils.js src/hg/js/utils.js
index 20875d2..6fc2364 100644
--- src/hg/js/utils.js
+++ src/hg/js/utils.js
@@ -3993,57 +3993,57 @@
 
 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(triggeringMouseMoveEv, currTooltip) {
-    /* Called after 100ms of the mouse being stationary, show a new tooltip
+    /* Called after 500ms of the mouse being stationary, show a new tooltip
      * if we are over a new mouseover-able element */
     e = triggeringMouseMoveEv;
     if (mousedNewItem && !(mouseIsOverPopup(e, currTooltip, 0))) {
         mousemoveController.abort();
         hideMouseoverText(currTooltip);
         showMouseoverText(triggeringMouseMoveEv);
     }
 }
 
 function mousemoveHelper(e) {
     /* Helper function for deciding whether to keep a tooltip visible upon a mousemove event */
     if (mousemoveTimer) {
         clearTimeout(mousemoveTimer);
     }
     mousemoveTimer = setTimeout(mousemoveTimerHelper, 500, e, this);
     // we are moving the mouse away, hide the tooltip regardless how much time has passed
     if (!(mouseIsOverPopup(e, this) || mouseIsOverItem(e, this))) {
         mousemoveController.abort();
         hideMouseoverText(this);
         return;
     }
 }
 
 function showMouseoverText(ev) {
     /* If a tooltip is not visible, show the tooltip text right away. If a tooltip
-     * is viisble, do nothing as the mousemove event helper will re-call us
+     * is visble, do nothing as the mousemove event helper will re-call us
      * after hiding the tooltip that is shown */
     ev.preventDefault();
     let referenceElement = lastMouseoverEle;
 
     if (!tooltipIsVisible()) {
         let tooltipDivId = "#" + referenceElement.getAttribute("mouseoverid");
         let tooltipDiv = $(tooltipDivId)[0];
         if (!tooltipDiv) {
             return;
         }
         mouseoverContainer.replaceChildren();
         let divCpy = tooltipDiv.cloneNode(true);
         divCpy.childNodes.forEach(function(n) {
             mouseoverContainer.appendChild(n);
         });
@@ -4104,42 +4104,39 @@
             // meaning we got here without calling addMouseover(), this should not happen
             // but catch it to be safe
             return;
         }
     }
 
     // if a tooltip is currently visible, we need to wait for its mousemove
     // event to clear it before we can show this one, ie a user "hovers"
     // this element on their way to mousing over the shown mouseover
     mousedNewItem = true;
     lastMouseoverEle = ele1;
     if (mouseoverTimer) {
         // user is moving their mouse around, make sure where they stop is what we show
         clearTimeout(mouseoverTimer);
     }
+    if (mousemoveTimer) {
+        // user is moving their mouse around and has triggered a potentially triggered
+        // a new pop up, clear the move timeout
+        clearTimeout(mousemoveTimer);
+    }
     // If there is no tooltip present, we want a small but noticeable delay
     // before showing a tooltip
     if (canShowNewMouseover) {
-        if (!tooltipIsVisible()) {
         mouseoverTimer = setTimeout(showMouseoverText, 500, e);
-        } else {
-            // the user has a tooltip visible already, so our timer for showing
-            // a new one can be shorter because the user expects another one to
-            // pop up, but we still need to be conscious that they may be moving
-            // the mouse to the tooltip itself. The mousemoveHelper() deals with that
-            mouseoverTimer = setTimeout(showMouseoverText, 300, e);
-        }
     }
 }
 
 function addMouseover(ele1, text = null, ele2 = null) {
     /* Adds wrapper elements to control various mouseover events */
     if (!mouseoverContainer) {
         mouseoverContainer = document.createElement("div");
         mouseoverContainer.className = "tooltip";
         mouseoverContainer.style.position = "fixed";
         mouseoverContainer.style.display = "inline-block";
         mouseoverContainer.style.visibility = "hidden";
         mouseoverContainer.style.opacity = "0";
         mouseoverContainer.id = "mouseoverContainer";
         let tooltipTextSize = localStorage.getItem("tooltipTextSize");
         if (tooltipTextSize === null) {tooltipTextSize = window.browserTextSize;}