7340e66cb860fa73cc651af31eb8fda2b668cb0d
max
  Wed Apr 5 11:41:31 2017 -0700
Modifying zoom dialog box so one does not have to see it by using
the modifier keys Alt or Ctrl/Cmd. Also allowing user to choose a color for the
highlight and allowing to delete all highlights in the View menu. refs #19118

diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index 5886fd9..f8916e0 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -957,66 +957,96 @@
         $(form).attr('method','get');
     },
 
     restoreFromBackButton: function()
     // Re-enabling vis dropdowns is necessary because initForAjax() disables them on submit.
     {
         $('select.normalText,select.hiddenText').attr('disabled',false);
     }
 };
 
   ////////////////////////////////////////////////////////////
  // dragSelect is also known as dragZoom or shift-dragZoom //
 ////////////////////////////////////////////////////////////
 var dragSelect = {
 
+    hlColorDefault: '#aaedff', // default highlight color, if nothing specified
+    hlColor :       '#aaedff', // current highlight color
     areaSelector:    null, // formerly "imgAreaSelect". jQuery element used for imgAreaSelect
     originalCursor:  null,
     startTime:       null,
 
     selectStart: function (img, selection)
     {
         initVars();
         if (rightClick.menu) {
             rightClick.menu.hide();
         }
         var now = new Date();
         dragSelect.startTime = now.getTime();
         posting.blockMapClicks();
+
     },
 
     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;
     },
 
-    highlightThisRegion: function(newPosition, doAdd)
+    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()
+        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;
+    },
+
+    highlightThisRegion: function(newPosition, doAdd, hlColor)
     // set highlighting newPosition in server-side cart and apply the highlighting in local UI.
     {
-        var hlColor = '#1ff3f0';
+        var hlColorName = hlColor; // js convention: do not assign to argument variables
+        if (hlColor==="" || hlColor===null || hlColor===undefined)
+            hlColorName = dragSelect.hlColor;
+
         var pos = parsePosition(newPosition);
         var start = pos.start;
         var end = pos.end;
-        var newHighlight = getDb() + "." + pos.chrom + ":" + start + "-" + end + hlColor;
+        var newHighlight = 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;
         }
         // we include enableHighlightingDialog because it may have been changed by the dialog
         var cartSettings = {             'highlight': hgTracks.highlight, 
                           'enableHighlightingDialog': hgTracks.enableHighlightingDialog ? 1 : 0 };
 
         if (hgTracks.windows && !hgTracks.virtualSingleChrom) {
@@ -1033,51 +1063,94 @@
                     var ce = e - w.virtStart + w.winStart;
                     if (nonVirtChrom === "") {
                         nonVirtChrom = w.chromName;
                         nonVirtStart = cs; 
                         nonVirtEnd   = ce;
                     } else {
                         if (w.chromName === nonVirtChrom) {
                             nonVirtEnd = Math.max(ce, nonVirtEnd);
                         } else {
                             break;
                         }
                     }
                 }
             }
             if (nonVirtChrom !== "")
-                cartSettings.nonVirtHighlight = getDb() + '.' + nonVirtChrom + ':' + nonVirtStart + '-' + (nonVirtEnd+1) + hlColor;
+                cartSettings.nonVirtHighlight = 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();
     },
 
     selectionEndDialog: function (newPosition)
     // Let user choose between zoom-in and highlighting.
     {   
+        // if the user hit Escape just before, do not show this dialog
+        if (dragSelect.startTime===null)
+            return;
         var dragSelectDialog = $("#dragSelectDialog")[0];
         if (!dragSelectDialog) {
-            $("body").append("<div id='dragSelectDialog'><span id='dragSelectPosition'></span>" + 
-                             "<p><input type='checkbox' id='disableDragHighlight'>" + 
-                             "Don't show this dialog again and always zoom.<BR>" + 
-                             "(Re-enable highlight via the 'configure' menu at any time.)</p>"+ 
-                             "Using the keyboard, you can highlight the current range with 'h then m' (mark) and clear all highlights with 'h then c'. Type '?' to show the other shortcuts.<p>");
+            $("body").append("<div id='dragSelectDialog'>" + 
+                             "<p><ul>"+
+                             "<li>Hold <b>Shift+drag</b> to show this dialog or zoom" +
+                             "<li>Hold <b>Alt+drag</b> to add a highlight (no dialog)" +
+                             "<li>Hold <b>Ctrl+drag</b> or <b>Cmd+drag</b> to zoom (no dialog)" +
+                             "<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>Clear all highlights with View - Clear Highlights or <tt>h then c</tt>" +
+                             "</ul></p>" +
+                             "<p>Highlight color: <input type='text' style='width:70px' id='hlColorInput' value='"+dragSelect.hlColor+"'>" +
+                             //"<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 the 'configure' menu</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);
+            });
+            // 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,
+                preferredFormat: "hex",
+                change: function() { var color = $("#hlColorPicker").spectrum("get"); $('#hlColorInput').val(color); },
+                };
+            $("#hlColorPicker").spectrum(opt);
+            // update the color picker if you change the input box
+            $("#hlColorInput").change(function(){ $("#hlColorPicker").spectrum("set", $('#hlColorInput').val()); });
+        }
+
+        $("#hlColorPicker").spectrum("set", $('#hlColorInput').val());
+
         if (hgTracks.windows) {
             var i,len;
             var newerPosition = newPosition;
             if (hgTracks.virtualSingleChrom && (newPosition.search("virt:")===0)) {
                 newerPosition = genomePos.disguisePosition(newPosition);
             }
             var str = newerPosition + "<br>\n";
             var str2 = "<br>\n";
             str2 += "<ul style='list-style-type:none; max-height:200px; padding:0; width:80%; overflow:hidden; overflow-y:scroll;'>\n";
             var pos = parsePosition(newPosition);
             var start = pos.start - 1;
             var end = pos.end;
             var selectedRegions = 0;
             for (i=0,len=hgTracks.windows.length; i < len; ++i) {
                 var w = hgTracks.windows[i];
@@ -1094,162 +1167,201 @@
             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: 450,
+                minWidth: 500,
                 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("virt:")===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);
                         $(this).dialog("close");
                     },
                     "Add Highlight": function() {
                         // Highlight selection
                         if ($("#disableDragHighlight").attr('checked'))
                             hgTracks.enableHighlightingDialog = false;
+                        dragSelect.hlColor = $("#hlColorInput").val();
                         dragSelect.highlightThisRegion(newPosition, true);
                         $(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"))
                         genomePos.revertToOriginalPos();
                     if ($("#disableDragHighlight").attr('checked'))
                         $(this).remove();
                     else
                         $(this).hide();
                     $('body').css('cursor', ''); // Occasionally wait cursor got left behind
+                    $("#hlColorPicker").spectrum("hide");
                 }
         });
         $(dragSelectDialog).dialog('open');
+        
+        // put the cursor into the input field
+        // we are not doing this for now - default behavior was to zoom when enter was pressed
+        // so people may still expect that "enter" on the dialog will zoom.
+        //var el = $("#hlColorInput")[0];
+        //el.selectionStart = 0;
+        //el.selectionEnd = el.value.length;
+        //el.focus();
+
     },
 
-    selectEnd: function (img, selection)
+    selectEnd: function (img, selection, event)
     {
         var now = new Date();
         var doIt = false;
+        var rulerClicked = selection.y1 <= hgTracks.rulerClickHeight;
         if (dragSelect.originalCursor)
             jQuery('body').css('cursor', dragSelect.originalCursor);
         // ignore releases outside of the image rectangle (allowing a 10 pixel slop)
         if (genomePos.check(img, selection)) {
             // ignore single clicks that aren't in the top of the image
             // (this happens b/c the clickClipHeight test in dragSelect.selectStart
             // doesn't occur when the user single clicks).
-            doIt = dragSelect.startTime !== null || selection.y1 <= hgTracks.rulerClickHeight;
+            doIt = dragSelect.startTime !== null || rulerClicked;
         }
+
         if (doIt) {
             // dragSelect.startTime is null if mouse has never been moved
             var singleClick = (  (selection.x2 === selection.x1)
                               || dragSelect.startTime === null
                               || (now.getTime() - dragSelect.startTime) < 100);
             var newPosition = genomePos.update(img, selection, singleClick);
             if (newPosition) {
-                if (hgTracks.enableHighlightingDialog)
+                if (event.altKey) {
+                    // with the alt-key, only highlight the region, do not zoom
+                    dragSelect.highlightThisRegion(newPosition, true);
+                    $(imageV2.imgTbl).imgAreaSelect({hide:true});
+                } else {
+                    if (hgTracks.enableHighlightingDialog && !(event.metaKey || event.ctrlKey))
+                        // don't show the dialog if: clicked on ruler, if dialog deactivated or meta/ctrl was pressed
                         dragSelect.selectionEndDialog(newPosition);
                     else {
+                        // in every other case, show the dialog
                         $(imageV2.imgTbl).imgAreaSelect({hide:true});
                         if (imageV2.inPlaceUpdate) {
                             if (hgTracks.virtualSingleChrom && (newPosition.search("virt:")===0)) {
                                 newPosition = genomePos.disguisePosition(newPosition); // DISGUISE
                             }
                             imageV2.navigateInPlace("position=" + newPosition, null, true);
                         } else {
                             jQuery('body').css('cursor', 'wait');
                             document.TrackHeaderForm.submit();
                         }
                     }
                 }
             } else {
                 $(imageV2.imgTbl).imgAreaSelect({hide:true});
                 genomePos.revertToOriginalPos();
             }
             dragSelect.startTime = null;
             // blockMapClicks/allowMapClicks() is necessary if selectEnd was over a map item.
             setTimeout(posting.allowMapClicks,50);
             return true;
+        }
     },
 
     load: function (firstTime)
     {
         var imgHeight = 0;
         if (imageV2.enabled)
             imgHeight = imageV2.imgTbl.innerHeight() - 1; // last little bit makes border look ok
         
+
         // No longer disable without ruler, because shift-drag still works
         if (typeof(hgTracks) !== "undefined") {
 
             if (hgTracks.rulerClickHeight === undefined || hgTracks.rulerClickHeight === null)
                 hgTracks.rulerClickHeight = 0; // will be zero if no ruler track
             var heights = hgTracks.rulerClickHeight;
 
             dragSelect.areaSelector = jQuery((imageV2.imgTbl).imgAreaSelect({
                 selectionColor:  'blue',
                 outerColor:      '',
                 minHeight:       imgHeight,
                 maxHeight:       imgHeight,
                 onSelectStart:   dragSelect.selectStart,
                 onSelectChange:  dragSelect.selectChange,
                 onSelectEnd:     dragSelect.selectEnd,
                 autoHide:        false, // gets hidden after possible dialog
                 movable:         false,
                 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.startTime = null;
+                }
+            });
+
+            // hide and redraw all current highlights when the browser window is resized
+            $(window).resize(function() {
+                $(imageV2.imgTbl).imgAreaSelect({hide:true});
+                imageV2.highlightRegion();
+            });
+
         }
     }
 };
 
   /////////////////////////////////////
  //// 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
     //          if drag, then create href from bpDown to bpUp
     //          if ctrlKey then expand selection to containing cytoBand(s)
@@ -1986,31 +2098,31 @@
 
     initialize();
 
     function initialize(){
 
         $(pan).parents('td.tdData').mousemove(function(e) {
             if (e.shiftKey)
                 $(this).css('cursor',"crosshair");  // shift-dragZoom
             else if ( theClient.isIePre11() )     // IE will override map item cursors if this gets set
                 $(this).css('cursor',"");  // normal pointer when not over clickable item
         });
 
         panAdjustHeight(prevX);
 
         pan.mousedown(function(e){
-             if (e.which > 1 || e.button > 1 || e.shiftKey)
+             if (e.which > 1 || e.button > 1 || e.shiftKey || e.metaKey || e.altKey || e.ctrlKey)
                  return true;
             if (mouseIsDown === false) {
                 if (rightClick.menu) {
                     rightClick.menu.hide();
                 }
                 mouseIsDown = true;
                 mouseDownX = e.clientX;
                 highlightArea = $('#highlightItem')[0];
                 atEdge = (!beyondImage && (prevX >= leftLimit || prevX <= rightLimit));
                 $(document).bind('mousemove',panner);
                 $(document).bind( 'mouseup', panMouseUp);  // Will exec only once
                 return false;
             }
         });
     }
@@ -2289,30 +2401,31 @@
     }
 
 
 };
 
   ///////////////////////////////////////
  //// rightClick (aka context menu) ////
 ///////////////////////////////////////
 var rightClick = {
 
     menu: null,
     selectedMenuItem: null,   // currently choosen context menu item (via context menu).
     floatingMenuItem: null,
     currentMapItem:   null,
     supportZoomCodon: false,  // turns on experimental feature (currently only in larry's tree).
+    clickedHighlightIdx : null,  // the index (0,1,...) of the highlight item that overlaps the last right-click
 
     makeMapItem: function (id)
     {   // Create a dummy mapItem on the fly
         // (for objects that don't have corresponding entry in the map).
         if (id && id.length > 0 && hgTracks.trackDb) {
             var title;
             var rec = hgTracks.trackDb[id];
             if (rec) {
                 title = rec.shortLabel;
             } else {
                 title = id;
             }
             return {id: id, title: "configure " + title};
         } else {
             return null;
@@ -2451,40 +2564,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);
+                                dragSelect.highlightThisRegion(newPos2, true, dragSelect.hlColorDefault);
                                 }
 
                         } 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);
+                            dragSelect.highlightThisRegion(newPos3, true, dragSelect.hlColorDefault);
                         }
                     } 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];
                             }
@@ -2653,55 +2766,60 @@
             rec = hgTracks.trackDb[id];
             if (tdbIsSubtrack(rec)) {
                 row = $( 'tr#tr_' + id );
                 rows = dragReorder.getCompositeSet(row);
                 // from bottom up, just in case remove screws with us
                 if (rows && rows.length > 0) {
                     for (var rIx=rows.length - 1; rIx >= 0; rIx--) {
                         $(rows[rIx]).remove();
                     }
                 selectUpdated = vis.update(rec.parentTrack, 'hide');
                 cart.setVars( [rec.parentTrack], ['hide']);
                 imageV2.afterImgChange(true);
                 }
             }
         } else if (cmd === 'jumpToHighlight') { // If highlight exists for this assembly, jump to it
-            if (hgTracks.highlight) {
-                var newPos = parsePositionWithDb(hgTracks.highlight);
+            if (hgTracks.highlight && rightClick.clickedHighlightIdx!==null) {
+                var newPos = parsePositionWithDb(hgTracks.highlight.split("|")[rightClick.clickedHighlightIdx]);
                 if (newPos && newPos.db === getDb()) {
                     if ( $('#highlightItem').length === 0) { // not visible? jump to it
                         var curPos = parsePosition(genomePos.get());
                         var diff = ((curPos.end - curPos.start) - (newPos.end - newPos.start));
                         if (diff > 0) { // new position is smaller then current, then center it
                             newPos.start = Math.max( Math.floor(newPos.start - (diff/2) ), 0 );
                             newPos.end   = newPos.start + (curPos.end - curPos.start);
                         }
                     }
                     if (imageV2.inPlaceUpdate) {
                         var params = "position=" + newPos.chrom+':'+newPos.start+'-'+newPos.end;
                         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') {
-            hgTracks.highlight = null;
-            cart.setVarsObj({ 'highlight': '[]' });
+
+            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();
+
         } else {   // if ( cmd in 'hide','dense','squish','pack','full','show' )
             // Change visibility settings:
             //
             // First change the select on our form:
             rec = hgTracks.trackDb[id];
             selectUpdated = vis.update(id, cmd);
 
             // Now change the track image
             if (imageV2.enabled && cmd === 'hide') {
                 // Hide local display of this track and update server side cart.
                 // Subtracks controlled by 2 settings so del vis and set sel=0.
                 if (tdbIsSubtrack(rec)) {
                     // Remove subtrack level vis and explicitly uncheck.
                     cart.setVars( [ id, id+"_sel" ], [ '[]', 0 ] ); 
                 } else if (tdbIsFolderContent(rec)) {
@@ -3034,64 +3152,70 @@
                       };
                 }
                 if (jQuery.floatMgr) {
                     o[(rightClick.selectedMenuItem.id === rightClick.floatingMenuItem ?
                             selectedImg : blankImg) + " float"] = {
                         onclick: function(menuItemClicked, menuObject) {
                             rightClick.hit(menuItemClicked, menuObject, "float");
                             return true; }
                     };
                 }
                 menu.push($.contextMenu.separator);
                 menu.push(o);
             }
 
             menu.push($.contextMenu.separator);
-            if (hgTracks.highlight) {
+            if (hgTracks.highlight && rightClick.clickedHighlightIdx!==null) {
+
                 if (hgTracks.highlight.search(getDb() + '.') === 0) {
                     var currentlySeen = ($('#highlightItem').length > 0); 
                     o = {};
                     // Jumps to highlight when not currently seen in image
-                    var text = (currentlySeen ? " Zoom" : " Jump") + " to highlighted region";
+                    var text = (currentlySeen ? " Zoom" : " Jump") + " to highlight";
                     o[rightClick.makeImgTag("highlightZoom.png") + text] = {
                         onclick: rightClick.makeHitCallback('jumpToHighlight')
                     };
 
                     if ( currentlySeen ) {   // Remove only when seen
                         o[rightClick.makeImgTag("highlightRemove.png") + 
-                                                                   " Remove highlighting"] = {
+                                                                   " Remove highlight"] = {
                             onclick: rightClick.makeHitCallback('removeHighlight')
                         };
                     }
                     menu.push(o);
                 }
             }
             // Add view image at end
             o = {};
             o[rightClick.makeImgTag("eye.png") + " View image"] = {
                 onclick: function(menuItemClicked, menuObject) {
                     rightClick.hit(menuItemClicked, menuObject, "viewImg");
                     return true; }
             };
             menu.push(o);
 
             return menu;
         },
         {
             beforeShow: function(e) {
                 // console.log(mapItems[rightClick.selectedMenuItem]);
                 rightClick.selectedMenuItem = rightClick.findMapItem(e);
+                // some right-click functions need to know the clicked chrom position
+                var xDiff = e.clientX - imageV2.imgTbl[0].getBoundingClientRect().left; // current position - position of table
+                var clickPos = genomePos.pixelsToBases(img, xDiff, xDiff+1, hgTracks.winStart, hgTracks.winEnd);
+                rightClick.clickedHighlightIdx = dragSelect.findHighlightIdxForPos(clickPos);
+
                 // XXXX? posting.blockUseMap = true;
                 return true;
             },
             hideTransition:'hide', // hideCallback fails if these are not defined.
             hideSpeed:10,
             hideCallback: function() {
                 $('p.btn.blueButtons').removeClass('blueButtons');
                 $('tr.trDraggable.greenRows').removeClass('greenRows');
             }
         });
         return;
     }
 };
 
   //////////////////////////////////
@@ -3309,31 +3433,31 @@
         $('#hgTracksDialog').dialog('open');
     
     }
 };
 
 // A function to show the keyboard help dialog box, bound to ? and called from the menu bar
 function showHotkeyHelp() {
     $("#hotkeyHelp").dialog({width:'600'});
 }
 
 // A function to add an entry for the keyboard help dialog box to the menubar 
 // and add text that indicates the shortcuts to many static menubar items as suggested by good old IBM CUA/SAA
 function addKeyboardHelpEntries() {
     var html = '<li><a id="keybShorts" title="List all possible keyboard shortcuts" href="#">Keyboard Shortcuts</a><span class="shortcut">?</span></li>';
     $('#help .last').before(html);
-    $("#keybShorts").onclick = function(){showHotKeyHelp(); return false;};
+    $("#keybShorts").click( function(){showHotkeyHelp();} );
 
     html = '<span class="shortcut">s s</span>';
     $('#sessionsMenuLink').after(html);
 
     html = '<span class="shortcut">p s</span>';
     $('#publicSessionsMenuLink').after(html);
 
     html = '<span class="shortcut">c t</span>';
     $('#customTracksMenuLink').after(html);
 
     html = '<span class="shortcut">t h</span>';
     $('#trackHubsMenuLink').after(html);
 
     html = '<span class="shortcut">t b</span>';
     $('#blatMenuLink').after(html);
@@ -4243,31 +4367,31 @@
             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()
     // highlight vertical region in imgTbl based on hgTracks.highlight (#709).
     {
         var pos;
-        var hexColor = '#FFAAAA';
+        var hexColor = dragSelect.hlColorDefault;
         $('.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()