f4a41965d1f5c26bcae644bba6777e141d485a95
max
  Wed Sep 8 01:56:09 2021 -0700
merging highlight-color-sticking into master, refs #28098

Squashed commit of the following:

commit f09bd0dcc1c23a91aae3c07610066b28e5177d82
Author: Max <max@soe.ucsc.edu>
Date:   Tue Sep 7 03:02:46 2021 -0700

Adding another anonymous function, to make sure that the page load does not crash because one of the .js files is not loaded yet, refs #28090

commit 5934e12f75e610bb8ff699dc17be5743a4b17c37
Author: Max <max@soe.ucsc.edu>
Date:   Tue Sep 7 02:36:40 2021 -0700

Fixing a super annoying CSS bug in our dialog box where the buttons moved on hover, and adding a 'save color' button to the highlight dialogbox. Not a perfect solution, but adresses the missing save button problem at least for now, refs #28090

commit 1d6a87e7303297c61637591807b338294cc1dcec
Author: Max <max@soe.ucsc.edu>
Date:   Thu Sep 2 08:23:00 2021 -0700

updated shift-drag dialog, refs #28090

commit 4e078c875f10d5b23d9540ec8dd3efba7b3af4c9
Author: Max <max@soe.ucsc.edu>
Date:   Thu Sep 2 06:35:36 2021 -0700

saving previous picked highlight color to the cart, refs #28090

diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index 585daca..0f5a650 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -11,30 +11,32 @@
 
 /* Data passed in from CGI via the hgTracks object:
  *
  * string cgiVersion      // CGI_VERSION
  * string chromName       // current chromosome
  * int winStart           // genomic start coordinate (0-based, half-open)
  * int winEnd             // genomic end coordinate
  * int newWinWidth        // new width (in bps) if user clicks on the top ruler
  * boolean revCmplDisp    // true if we are in reverse display
  * int insideX            // width of side-bar (in pixels)
  * int rulerClickHeight   // height of ruler (in pixels) - zero if ruler is hidden
  * boolean inPlaceUpdate  // true if in-place-update is turned on
  * int imgBox*            // various drag-scroll values
  * boolean measureTiming  // true if measureTiming is on
  * Object trackDb         // hash of trackDb entries for tracks which are visible on current page
+ * string highlight       // highlight string, in format chrom#start#end#color|chrom2#start2#end2#color2|...
+ * string prevHlColor     // the last highlight color that the user picked
  */
 
 /* IE11 compatibility - IE doesn't have string startsWith and never will */
 if (!String.prototype.startsWith) {
   String.prototype.startsWith = function(searchString, position) {
     position = position || 0;
     return this.indexOf(searchString, position) === position;
   };
 }
 
 function initVars()
 {  // There are various entry points, so we call initVars in several places to make sure all is well
     if (typeof(hgTracks) !== "undefined" && !genomePos.original) {
         // remember initial position and size so we can restore it if user cancels
         genomePos.original = genomePos.getOriginalPos();
@@ -959,31 +961,31 @@
     },
     
     initForAjax: function()
     {   // To better support the back-button, it is good to eliminate extraneous form puts
         // Towards that end, we support visBoxes making ajax calls to update cart.
         var sels = $('select.normalText,select.hiddenText');
         $(sels).change(function() {
             var track = $(this).attr('name');
             if ($(this).val() === 'hide') {
                 var rec = hgTracks.trackDb[track];
                 if (rec)
                     rec.visibility = 0;
                 // else Would be nice to hide subtracks as well but that may be overkill
                 $(document.getElementById('tr_' + track)).remove();
                 cart.updateSessionPanel();
-                imageV2.highlightRegion();
+                imageV2.drawHighlights();
                 $(this).attr('class', 'hiddenText');
             } else
                 $(this).attr('class', 'normalText');
             
             cart.setVars([track], [$(this).val()]);
             imageV2.markAsDirtyPage();
             return false;
         });
         // Now we can rid the submt of the burden of all those vis boxes
         var form = $('form#TrackForm');
         $(form).submit(function () {
             $('select.normalText,select.hiddenText').attr('disabled',true);
         });
         $(form).attr('method','get');
     },
@@ -1022,59 +1024,85 @@
     selectChange: function (img, selection)
     {
         if (selection.x1 !== selection.x2) {
             if (genomePos.check(img, selection)) {
                 genomePos.update(img, selection, false);
                 jQuery('body').css('cursor', dragSelect.originalCursor);
             } else {
                 jQuery('body').css('cursor', 'not-allowed');
             }
         }
         return true;
     },
 
     findHighlightIdxForPos : function(findPos) {
         // return the index of the highlight string e.g. hg19.chrom1:123-345#AABBDCC that includes a chrom range findPos
-        // mostly copied from highlightRegion()
+        // mostly copied from drawHighlights()
         var currDb = getDb();
         if (hgTracks.highlight) {
             var hlArray = hgTracks.highlight.split("|"); // support multiple highlight items
             for (var i = 0; i < hlArray.length; i++) {
                 hlString = hlArray[i];
                 pos = parsePositionWithDb(hlString);
                 imageV2.undisguiseHighlight(pos);
 
                 if (!pos) 
                     continue; // ignore invalid position strings
                 pos.start--;
 
                 if (pos.chrom === hgTracks.chromName && pos.db === currDb
                 &&  pos.start <= findPos.chromStart && pos.end >= findPos.chromEnd) {
                     return i;
                 }
             }
         }
         return null;
     },
 
+    saveHlColor : function (hlColor) 
+    // save the current hlColor to the object and also the cart variable hlColor and return it.
+    // hlColor is a 6-character hex string prefixed by #
+    {
+            dragSelect.hlColor = hlColor;
+            cart.setVars(["prevHlColor"], [dragSelect.hlColor]);
+            hgTracks.prevHlColor = hlColor; // cart.setVars does not update the hgTracks-variables. The cart-variable system is a problem.
+            return hlColor;
+    },
+
+    loadHlColor : function () 
+    // load hlColor from prevHlColor in the cart, or use default color, set and return it
+    // color is a 6-char hex string prefixed by #
+    {
+        if (hgTracks.prevHlColor)
+            dragSelect.hlColor = hgTracks.prevHlColor;
+        else
+            dragSelect.hlColor = dragSelect.hlColorDefault;
+        return dragSelect.hlColor;
+    },
+
     highlightThisRegion: function(newPosition, doAdd, hlColor)
     // set highlighting newPosition in server-side cart and apply the highlighting in local UI.
+    // hlColor can be undefined, in which case it defaults to the last used color or the default light blue
+    // if hlColor is set, it is also saved into the cart.
+    // if doAdd is true, the highlight is added to the current list. If it is false, all old highlights are deleted.
     {
         newPosition.replace("virt:", "multi:");
-        var hlColorName = hlColor; // js convention: do not assign to argument variables
+        var hlColorName = null;
         if (hlColor==="" || hlColor===null || hlColor===undefined)
-            hlColorName = dragSelect.hlColor;
+            hlColorName = dragSelect.loadHlColor();
+        else
+            hlColorName = dragSelect.saveHlColor( hlColor );
 
         var pos = parsePosition(newPosition);
         var start = pos.start;
         var end = pos.end;
         var newHighlight = makeHighlightString(getDb(), pos.chrom, start, end, hlColorName);
         newHighlight = imageV2.disguiseHighlight(newHighlight);
         var oldHighlight = hgTracks.highlight;
         if (oldHighlight===undefined || doAdd===undefined || doAdd===false || oldHighlight==="") {
             // just set/overwrite the old highlight position, this used to be the default
             hgTracks.highlight = newHighlight;
         }
         else {
             // add to the end of a |-separated list
             hgTracks.highlight = oldHighlight+"|"+newHighlight;
         }
@@ -1102,64 +1130,67 @@
                         if (w.chromName === nonVirtChrom) {
                             nonVirtEnd = Math.max(ce, nonVirtEnd);
                         } else {
                             break;
                         }
                     }
                 }
             }
             if (nonVirtChrom !== "")
                 cartSettings.nonVirtHighlight = makeHighlightString(getDb(), nonVirtChrom, nonVirtStart, (nonVirtEnd+1), hlColorName);
         } else if (hgTracks.windows && hgTracks.virtualSingleChrom) {
                 cartSettings.nonVirtHighlight = hgTracks.highlight;
         }
         // TODO if not virt, do we need to erase cart nonVirtHighlight ?
         cart.setVarsObj(cartSettings);
-        imageV2.highlightRegion();
+        imageV2.drawHighlights();
     },
 
     selectionEndDialog: function (newPosition)
     // Let user choose between zoom-in and highlighting.
     {   
         newPosition.replace("virt:", "multi:");
         // if the user hit Escape just before, do not show this dialo
         if (dragSelect.startTime===null)
             return;
         var dragSelectDialog = $("#dragSelectDialog")[0];
         if (!dragSelectDialog) {
             $("body").append("<div id='dragSelectDialog'>" + 
                              "<p><ul>"+
                              "<li>Hold <b>Shift+drag</b> to show this dialog" +
-                             "<li>Hold <b>Alt+drag</b> to add a highlight" +
+                             "<li>Hold <b>Alt+drag</b> (Windows) or <b>Option+drag</b> (Mac) to add a highlight" +
                              "<li>Hold <b>Ctrl+drag</b> (Windows) or <b>Cmd+drag</b> (Mac) to zoom" +
-                             "<li>To cancel, press <tt>Esc</tt> anytime or drag mouse outside image" +
-                             "<li>Highlight the current position with <tt>h then m</tt>" +
+                             "<li>To cancel, press <tt>Esc</tt> anytime during the drag" +
+                             "<li>Using the keyboard, highlight the current position with <tt>h then m</tt>" +
                              "<li>Clear all highlights with View - Clear Highlights or <tt>h then c</tt>" +
+                             "<li>To merely save the color for the next keyboard or right-click &gt; Highlight operations, click 'Save Color' below" +
                              "</ul></p>" +
-                             "<p>Highlight color: <input type='text' style='width:70px' id='hlColorInput' value='"+dragSelect.hlColor+"'>" +
+                             "<p>Highlight color: <input type='text' style='width:70px' id='hlColorInput' value='"+dragSelect.loadHlColor()+"'>" +
                              //"<span id='hlColorBox' style='width:20px'></span>" + 
                              "&nbsp;&nbsp;<input id='hlColorPicker'>" + 
                              "&nbsp;&nbsp;<a href='#' id='hlReset'>Reset</a></p>" + 
                              "<input style='float:left' type='checkbox' id='disableDragHighlight'>" + 
                              "<span style='border:solid 1px #DDDDDD; padding:3px;display:inline-block' id='hlNotShowAgainMsg'>Don't show this again and always zoom with shift.<br>" + 
                              "Re-enable via 'View - Configure Browser' (<tt>c then f</tt>)</span></p>"+ 
                              "Selected chromosome position: <span id='dragSelectPosition'></span>");
             dragSelectDialog = $("#dragSelectDialog")[0];
             // reset value
             $('#hlReset').click(function() { 
-                $('#hlColorInput').val(dragSelect.hlColorDefault);
-                $("#hlColorPicker").spectrum("set", dragSelect.hlColorDefault);
+                var hlDefault = dragSelect.hlColorDefault;
+                $('#hlColorInput').val(hlDefault);
+                $("#hlColorPicker").spectrum("set", hlDefault);
+                dragSelect.saveHlColor(hlDefault);
             });
             // allow to click checkbox by clicking on the label
             $('#hlNotShowAgainMsg').click(function() { $('#disableDragHighlight').click();});
             // click "add highlight" when enter is pressed in color input box
             $("#hlColorInput").keyup(function(event){
                 if(event.keyCode == 13){
                     $(".ui-dialog-buttonset button:nth-child(3)").click();
                 }
             });
             // activate the color picker
             var opt = {
                 hideAfterPaletteSelect : true,
                 color : $('#hlColorInput').val(),
                 showPalette: true,
                 showInput: true,
@@ -1201,68 +1232,73 @@
             str2 += "</ul>\n";
             if (!(hgTracks.virtualSingleChrom && (selectedRegions === 1))) {
                 str += str2;
             }
             $("#dragSelectPosition").html(str);
         } else {
             $("#dragSelectPosition").html(newPosition);
         }
         $(dragSelectDialog).dialog({
                 modal: true,
                 title: "Drag-and-select",
                 closeOnEscape: true,
                 resizable: false,
                 autoOpen: false,
                 revertToOriginalPos: true,
-                minWidth: 500,
+                minWidth: 550,
                 buttons: {  
                     "Zoom In": function() {
                         // Zoom to selection
                         $(this).dialog("option", "revertToOriginalPos", false);
                         if ($("#disableDragHighlight").attr('checked'))
                             hgTracks.enableHighlightingDialog = false;
                         if (imageV2.inPlaceUpdate) {
                             if (hgTracks.virtualSingleChrom && (newPosition.search("multi:")===0)) {
                                 newPosition = genomePos.disguisePosition(newPosition); // DISGUISE
                             }
                             var params = "position=" + newPosition;
                             if (!hgTracks.enableHighlightingDialog)
                                 params += "&enableHighlightingDialog=0";
                             imageV2.navigateInPlace(params, null, true);
                         } else {
                             $('body').css('cursor', 'wait');
                             if (!hgTracks.enableHighlightingDialog)
                                 cart.setVarsObj({'enableHighlightingDialog': 0 },null,false); // async=false
                             document.TrackHeaderForm.submit();
                         }
                         $(this).dialog("close");
                     },
                     "Single Highlight": function() {
                         // Clear old highlight and Highlight selection
                         $(imageV2.imgTbl).imgAreaSelect({hide:true});
                         if ($("#disableDragHighlight").attr('checked'))
                             hgTracks.enableHighlightingDialog = false;
-                        dragSelect.hlColor = $("#hlColorInput").val();
-                        dragSelect.highlightThisRegion(newPosition, false);
+                        var hlColor = $("#hlColorInput").val();
+                        dragSelect.highlightThisRegion(newPosition, false, hlColor);
                         $(this).dialog("close");
                     },
                     "Add Highlight": function() {
                         // Highlight selection
                         if ($("#disableDragHighlight").attr('checked'))
                             hgTracks.enableHighlightingDialog = false;
-                        dragSelect.hlColor = $("#hlColorInput").val();
-                        dragSelect.highlightThisRegion(newPosition, true);
+                        var hlColor = $("#hlColorInput").val();
+                        dragSelect.highlightThisRegion(newPosition, true, hlColor);
+                        $(this).dialog("close");
+                    },
+                    "Save Color": function() {
+                        var hlColor = $("#hlColorInput").val();
+                        dragSelect.saveHlColor( hlColor );
                         $(this).dialog("close");
                     },
                     "Cancel": function() {
                         $(this).dialog("close");
                     }
                 },
 
                 open: function () { // Make zoom the focus/default action
                    $(this).parents('.ui-dialog-buttonpane button:eq(0)').focus(); 
                 },
 
                 close: function() {
                     // All exits to dialog should go through this
                     $(imageV2.imgTbl).imgAreaSelect({hide:true});
                     if ($(this).dialog("option", "revertToOriginalPos"))
@@ -1372,31 +1408,31 @@
                 clickClipHeight: heights
             }));
 
             // remove any ongoing drag-selects when the esc key is pressed anywhere for this document
             // This allows to abort zooming / highlighting
             $(document).keyup(function(e){
                 if(e.keyCode === 27) {
                     $(imageV2.imgTbl).imgAreaSelect({hide:true});
                     dragSelect.escPressed = true;
                 }
             });
 
             // hide and redraw all current highlights when the browser window is resized
             $(window).resize(function() {
                 $(imageV2.imgTbl).imgAreaSelect({hide:true});
-                imageV2.highlightRegion();
+                imageV2.drawHighlights();
             });
 
         }
     }
 };
 
   /////////////////////////////////////
  //// Chrom Drag/Zoom/Expand code ////
 /////////////////////////////////////
 jQuery.fn.chromDrag = function(){
 this.each(function(){
     // Plan:
     // mouseDown: determine where in map: convert to img location: pxDown
     // mouseMove: flag drag
     // mouseUp: if no drag, then create href centered on bpDown loc with current span
@@ -1869,31 +1905,31 @@
 
             // Outside image?  Then abandon.
             var curY = e.pageY;
             var imgTbl = $('#imgTbl');
             var north = $(imgTbl).offset().top;
             var south = north + $(imgTbl).height();
             if (curY < north || curY > south) {
                 atEdge = false;
                 beyondImage = false;
                 if (savedPosition)
                     genomePos.set(savedPosition);
                 var oldPos = prevX.toString() + "px";
                 $(".panImg").css( {'left': oldPos });
                 $('.tdData').css( {'backgroundPosition': oldPos } );
                 if (highlightAreas)
-                    imageV2.highlightRegion();
+                    imageV2.drawHighlights();
                 return true;
             }
 
             // Do we need to fetch anything?
             if (beyondImage) {
                 if (imageV2.inPlaceUpdate) {
                     var pos = parsePosition(genomePos.get());
                     imageV2.navigateInPlace("position=" +
                             encodeURIComponent(pos.chrom + ":" + pos.start + "-" + pos.end),
                             null, true);
                 } else {
                     document.TrackHeaderForm.submit();
                 }
                 return true; // Make sure the setTimeout below is not called.
             }
@@ -2253,40 +2289,40 @@
                         url += "&l=" + (chromStart - 1) + "&r=" + chromEnd;
                         url += "&db=" + getDb() + "&hgsid=" + getHgsid();
                         if ( ! window.open(url) ) {
                             rightClick.windowOpenFailedMsg();
                         }
                     } else if (cmd === 'highlightItem') {
                         if (hgTracks.windows && !hgTracks.virtualSingleChrom) {
                             // orig way only worked if the entire item was visible in the windows.
                             //var result = genomePos.chromToVirtChrom(chrom, parseInt(chromStart-1), parseInt(chromEnd));
 
                             var result = genomePos.convertChromPosToVirtCoords(chrom, parseInt(chromStart-1), parseInt(chromEnd));
 
                             if (result.chromStart != -1)
                                 {
                                 var newPos2 = hgTracks.chromName+":"+(result.chromStart+1)+"-"+result.chromEnd;
-                                dragSelect.highlightThisRegion(newPos2, true, dragSelect.hlColorDefault);
+                                dragSelect.highlightThisRegion(newPos2, true);
                                 }
 
                         } else {
                             var newChrom = hgTracks.chromName;
                             if (hgTracks.windows && hgTracks.virtualSingleChrom) {
                                 newChrom = hgTracks.windows[0].chromName;
                             }
                             var newPos3 = newChrom+":"+(parseInt(chromStart))+"-"+parseInt(chromEnd);
-                            dragSelect.highlightThisRegion(newPos3, true, dragSelect.hlColorDefault);
+                            dragSelect.highlightThisRegion(newPos3, true);
                         }
                     } else {
                         var newPosition = genomePos.setByCoordinates(chrom, chromStart, chromEnd);
                         var reg = new RegExp("hgg_gene=([^&]+)");
                         var b = reg.exec(href);
                         var name;
                         // pull item name out of the url so we can set hgFind.matches (redmine 3062)
                         if (b && b[1]) {
                             name = b[1];
                         } else {
                             reg = new RegExp("[&?]i=([^&]+)");
                             b = reg.exec(href);
                             if (b && b[1]) {
                                 name = b[1];
                             }
@@ -2533,31 +2569,31 @@
                         imageV2.navigateInPlace(params, null, true);
                     } else {
                         genomePos.setByCoordinates(newPos.chrom, newPos.start, newPos.end);
                         jQuery('body').css('cursor', 'wait');
                         document.TrackHeaderForm.submit();
                     }
                 }
             }
 
         } else if (cmd === 'removeHighlight') {
 
             var highlights = hgTracks.highlight.split("|");
             highlights.splice(rightClick.clickedHighlightIdx, 1); // splice = remove element from array
             hgTracks.highlight = highlights.join("|");
             cart.setVarsObj({'highlight' : hgTracks.highlight});
-            imageV2.highlightRegion();
+            imageV2.drawHighlights();
         } else if (cmd === 'toggleMerge') {
             // toggle both the cart (if the user goes to trackUi)
             // and toggle args[key], if the user doesn't leave hgTracks
             var key = id + ".doMergeItems";
             var updateObj = {};
             if (args[key] === 1) {
                 args[key] = 0;
                 updateObj[key] = 0;
                 cart.setVarsObj(updateObj,null,false);
                 imageV2.requestImgUpdate(id, id + ".doMergeItems=0");
             } else {
                 args[key] = 1;
                 updateObj[key] = 1;
                 cart.setVarsObj(updateObj,null,false);
                 imageV2.requestImgUpdate(id, id + ".doMergeItems=1");
@@ -3412,31 +3448,31 @@
         newPos = genomePos.disguisePosition(newPosition); // DISGUISE?
     imageV2.navigateInPlace("position="+newPos, null, true);
 }
 
 // A function for the keyboard shortcuts "highlight add/clear/new"
 function highlightCurrentPosition(mode) {
     var pos = genomePos.get();
     if (mode=="new")
         dragSelect.highlightThisRegion(pos, false);
     else if (mode=="add")
         dragSelect.highlightThisRegion(pos, true);
     else {
         hgTracks.highlight = "";
         var cartSettings = {'highlight': ""};
         cart.setVarsObj(cartSettings);
-        imageV2.highlightRegion();
+        imageV2.drawHighlights();
     }
 }
 
   //////////////////////////////////
  //// popup (aka modal dialog) ////
 //////////////////////////////////
 var popUp = {
 
     trackName:            "",
     trackDescriptionOnly: false,
     saveAllVars:          null,
 
     cleanup: function ()
     {  // Clean out the popup box on close
         if ($('#hgTrackUiDialog').html().length > 0 ) {
@@ -3772,60 +3808,60 @@
                                 }
                                 $("#goButton").click();
                             },
                             function (position) {
                                 genomePos.set(position, getSizeFromCoordinates(position));
                             }
                 );
             }
         }
     },
     
     afterImgChange: function (dirty)
     {   // Standard things to do when manipulations change image without ajax update.
         dragReorder.init();
         dragSelect.load(false);
-        imageV2.highlightRegion();
+        imageV2.drawHighlights();
         if (dirty)
             imageV2.markAsDirtyPage();
     },
     
     afterReload: function (id)
     {   // Reload various UI widgets after updating imgTbl map.
         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.highlightRegion();
+                imageV2.drawHighlights();
                 return;
             }
         }
         
         imageV2.loadRemoteTracks();
         makeItemsByDrag.load();
         imageV2.loadSuggestBox();
-        imageV2.highlightRegion();
+        imageV2.drawHighlights();
 
         if (imageV2.backSupport) {
             imageV2.setInHistory(false);    // Set this new position into History stack
         } else {
             imageV2.markAsDirtyPage();
         }
     },
 
     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) {
@@ -4308,35 +4344,40 @@
     // undisguise highlight pos
     {
         // UN-DISGUISE
         if (hgTracks.virtualSingleChrom && (pos.chrom.search("multi") !== 0)) {
             var position = pos.chrom+":"+pos.start+"-"+pos.end;
             var newPosition = genomePos.undisguisePosition(position);
             var newPos = parsePosition(newPosition);
             if (newPos) {
                 pos.chrom = newPos.chrom;
                 pos.start = newPos.start;
                 pos.end   = newPos.end;
             }
         }
     },
 
-    highlightRegion: function()
+    drawHighlights: function()
     // highlight vertical region in imgTbl based on hgTracks.highlight (#709).
+    // For PDF/hgRenderTracks output, the highlights are drawn by hgTracks.c:drawHighlights()
     {
         var pos;
         var hexColor = dragSelect.hlColorDefault;
+        // if possible, re-use the color that the user picked last time
+        if (hgTracks.prevHlColor)
+            hexColor = hgTracks.prevHlColor;
+
         $('.highlightItem').remove();
         if (hgTracks.highlight) {
             var hlArray = hgTracks.highlight.split("|"); // support multiple highlight items
             for (var i = 0; i < hlArray.length; i++) {
                 hlString = hlArray[i];
                 pos = parsePositionWithDb(hlString);
                 // UN-DISGUISE
                 imageV2.undisguiseHighlight(pos);
                 if (pos) {
                     pos.start--;  // make start 0-based to match hgTracks.winStart
                     if (pos.color)
                         hexColor = pos.color;
                 }
 
                 if (pos && pos.chrom === hgTracks.chromName && pos.db === getDb() 
@@ -5108,38 +5149,38 @@
             $("div.scroller").panImages();
         }
 
         // Retrieve tracks via AJAX that may take too long to draw initialliy (i.e. a remote bigWig)
         var retrievables = $('#imgTbl').find("tr.mustRetrieve");
         if ($(retrievables).length > 0) {
             $(retrievables).each( function (i) {
                 var trackName = $(this).attr('id').substring(3);
                 imageV2.requestImgUpdate(trackName,"","");
             });
         }
         imageV2.loadRemoteTracks();
         makeItemsByDrag.load();
         
         // Any highlighted region must be shown and warnBox must play nice with it.
-        imageV2.highlightRegion();
+        imageV2.drawHighlights();
         // When warnBox is dismissed, any image highlight needs to be redrawn.
-        $('#warnOK').click(function (e) { imageV2.highlightRegion();});
+        $('#warnOK').click(function (e) { imageV2.drawHighlights();});
         // Also extend the function that shows the warn box so that it too redraws the highlight.
         showWarnBox = (function (oldShowWarnBox) {
             function newShowWarnBox() {
                 oldShowWarnBox.apply();
-                imageV2.highlightRegion();
+                imageV2.drawHighlights();
             }
             return newShowWarnBox;
         })(showWarnBox);
     }
 
     // Drag select in chromIdeogram
     if ($('img#chrom').length === 1) {
         if ($('area.cytoBand').length >= 1) {
             $('img#chrom').chromDrag();
         }
     }
 
     // Track search uses tabs
     trackSearch.init();