447513356fcfa684846bdd1b63476e68d9c17ce9
chmalee
  Thu Apr 6 09:04:41 2023 -0700
Add code to create tooltips under our control. Convert title attributes
on hgTracks into these tooltips

diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index ff200cf..881a7e4 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -3872,44 +3872,50 @@
         dragReorder.init();
         dragSelect.load(false);
         // Do NOT reload context menu (otherwise we get the "context menu sticks" problem).
         // rightClick.load($('#tr_' + id));
         if (imageV2.imgTbl.tableDnDUpdate)
             imageV2.imgTbl.tableDnDUpdate();
         rightClick.reloadFloatingItem();
         // Turn on drag scrolling.
         if (hgTracks.imgBoxPortal) {
             $("div.scroller").panImages();
         }
         if (imageV2.backSupport) {
             if (id) { // The remainder is only needed for full reload
                 imageV2.markAsDirtyPage(); // vis of cfg change
                 imageV2.drawHighlights();
+                if (typeof showMouseovers !== 'undefined' && showMouseovers) {
+                    convertTitleTagsToMouseovers();
+                }
                 return;
             }
         }
         
         imageV2.loadRemoteTracks();
         makeItemsByDrag.load();
         imageV2.loadSuggestBox();
         imageV2.drawHighlights();
 
         if (imageV2.backSupport) {
             imageV2.setInHistory(false);    // Set this new position into History stack
         } else {
             imageV2.markAsDirtyPage();
         }
+        if (typeof showMouseovers !== 'undefined' && showMouseovers) {
+            convertTitleTagsToMouseovers();
+        }
     },
 
     updateImgForId: function (html, id, fullImageReload, newJsonRec)
     {   // update row in imgTbl for given id.
         // return true if we successfully pull slice for id and update it in imgTrack.
         var newTr = $(html).find("tr[id='tr_" + id + "']");
         if (newTr.length > 0) {
             var tr = $(document.getElementById("tr_" + id));
             if (tr.length > 0) {
                 $(tr).html(newTr.children());
 
                 // Need to update tr class list too
                 var classes = $(html).find("tr[id='tr_"+ id + "']")[0].className;
                 if (classes && classes.length > 0) {
                     $(tr).removeClass();
@@ -4117,30 +4123,31 @@
             if ( ! stripped.warnMsg )
                 warn("hgTracks object is missing from the response");
         } else {
             if (this.id) {
                 if (newJson.trackDb[this.id]) {
                     var visibility = vis.enumOrder[newJson.trackDb[this.id].visibility];
                     var limitedVis;
                     if (newJson.trackDb[this.id].limitedVis)
                         limitedVis = vis.enumOrder[newJson.trackDb[this.id].limitedVis];
                     if (this.newVisibility && limitedVis && this.newVisibility !== limitedVis)
                         // see redmine 1333#note-9
                         alert("There are too many items to display the track in " +
                                 this.newVisibility + " mode.");
                     var rec = oldJson.trackDb[this.id];
                     rec.limitedVis = newJson.trackDb[this.id].limitedVis;
+                    rec.imgOffsetY = newJson.trackDb[this.id].imgOffsetY;
                     vis.update(this.id, visibility);
                     if (visibility === "hide")
                         cart.updateSessionPanel(); // notify when vis change to hide track
                     valid = true;
                 } else {
                     // what got returned from the AJAX request was a different
                     // set of tracks.  Let's do a reload and hope for the best
                     imageV2.fullReload();
                 }
             } else {
                 valid = true;
             }
 
             suggestBox.restoreWatermark(getDb(), $("#suggestTrack").length > 0);
 
@@ -5287,60 +5294,74 @@
                 maxWidth: popMaxWidth,
                 modal: true,
                 closeOnEscape: true,
                 autoOpen: false,
                 buttons: downloadTrackDataButtons
             });
         }
         htmlStr = "<p>Use this selection window to download track data" +
             " for the current region (" + genomePos.get() + "). Please note that large regions" +
             " may be slow to download.</p>";
         htmlStr  += "<div><button id='checkAllDownloadTracks'>Check All</button>" +
             "&nbsp;" +
             "<button id='uncheckAllDownloadTracks'>Clear All</button>" +
             "</div>";
         _.each(hgTracks.trackDb, function(track, trackName) {
+            showDisabledMsg = false;
             if (!trackName.includes("Squish") && trackName !== "ruler" && track.visibility > 0) {
-                htmlStr += "<input type=checkbox checked class='downloadTrackName' id='" + trackName + "'>";
+                htmlStr += "<input type=checkbox class='downloadTrackName' id='" + trackName + "'";
+                if (trackName.startsWith("ct_")) {
+                    showDisabledMsg = true;
+                    htmlStr += " disabled ";
+                } else {
+                    htmlStr += " checked ";
+                }
+                htmlStr +=  ">";
                 htmlStr += "<label>" + track.shortLabel + "</label>";
                 htmlStr += "</input>";
+                if (showDisabledMsg) {
+                    htmlStr += "&nbsp;<span id='" + trackName + "Tooltip'> (?)</span>";
+                }
                 htmlStr += "<br>";
             }
         });
         htmlStr += "<div ><label style='padding-right: 10px' for='downloadFileName'>Enter an output file name</label>";
         htmlStr += "<input type=text size=30 class='downloadFileName' id='downloadFileName'" +
             " value='" + getDb() + ".tracks'</input>";
         htmlStr += "<br>";
         htmlStr += "<label style='padding-right: 10px' for='outputFormat'>Choose an output format</label>";
         htmlStr += "<select name='outputFormat' id='outputFormat'>";
         htmlStr += "<option selected value='json'>JSON</option>";
         htmlStr += "<option value='csv'>CSV</option>";
         htmlStr += "<option value='tsv'>TSV</option>";
         htmlStr += "</select>";
         htmlStr += "</div>";
         downloadDialog.innerHTML = htmlStr;
         $("#checkAllDownloadTracks").click( function() {
             $(".downloadTrackName").each(function(i, elem) {
                 elem.checked = true;
             });
         });
         $("#uncheckAllDownloadTracks").click( function() {
             $(".downloadTrackName").each(function(i, elem) {
                 elem.checked = false;
             });
         });
         $(downloadDialog).dialog('open');
+        $("[id$='Tooltip'").each(function(i, elem) {
+            addMouseover(elem, "This track must be downloaded with the Table Browser");
+        });
     }
 };
 
   ///////////////
  //// READY ////
 ///////////////
 $(document).ready(function()
 {
     imageV2.moveTiming();
 
     // hg.conf will turn this on 2020-10 - Hiram
     if (window.mouseOverEnabled) { mouseOver.addListener(); }
 
     // custom tracks get little trash icons
     $("div.trackDeleteIcon").click( onTrackDelIconClick );
@@ -5532,31 +5553,33 @@
 
 
     // add a 'link' to download the current track data (under hg.conf control)
     if (typeof showDownloadButton !== 'undefined' && showDownloadButton) {
         newListEl = document.createElement("li");
         newLink = document.createElement("a");
         newLink.setAttribute("id", "hgTracksDownload");
         newLink.setAttribute("name", "downloadTracks");
         newLink.textContent = "Download Current Track Data";
         newLink.href = "#";
         newListEl.appendChild(newLink);
         $("#downloads > ul")[0].appendChild(newListEl);
         $("#hgTracksDownload").click(downloadCurrentTrackData.showDownloadUi);
     }
 
-    
+    if (typeof showMouseovers !== 'undefined' && showMouseovers) {
+        convertTitleTagsToMouseovers();
+    }
 });
 
 function hgtWarnTiming(maxSeconds) {
     /* show a dialog box if the page load time was slower than x seconds. Has buttons to hide or never show this again. */
     var loadTime = window.performance.timing.domContentLoadedEventStart-window.performance.timing.navigationStart; /// in msecs
     var loadSeconds = loadTime/1000;
     if (loadSeconds < maxSeconds)
         return;
 
     var skipNotification = localStorage.getItem("hgTracks.hideSpeedNotification");
     dumpCart(loadSeconds, skipNotification);
         
     if (skipNotification)
         return;