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/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index dabba2f..34c25de 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -2215,33 +2215,34 @@
             // as a result of the multi-region code
             if (h->chromStart > 0)
                 {
                 h->chromStart--;
                 }
             slAddHead(&hlList, h);
             }
         }
 
     slReverse(&hlList);
     }
 
 return hlList;
 }
 
-static void highlightRegions(struct cart *cart, struct hvGfx *hvg, int imagePixelHeight)
-// Highlights regions in the image.  Only done if theImgBox is not defined.
-// Thus it is done for ps/pdf and view image but the hgTracks image is highlighted via js
+static void drawHighlights(struct cart *cart, struct hvGfx *hvg, int imagePixelHeight)
+// Draw the highlight regions in the image.  Only done if theImgBox is not defined.
+// Thus it is done for ps/pdf and view image but for html output the highlights are drawn 
+// on the javascript client by hgTracks.js > imageV2 > drawHighlights()
 {
 struct highlightVar *hlList = parseHighlightInfo();
 
 if(hlList && theImgBox == NULL) // Only highlight region when imgBox is not used. (pdf and show-image)
     {
     struct highlightVar *h;
     for (h=hlList; h; h=h->next)
         {
         if (virtualSingleChrom()) // DISGUISE VMODE
             {
             if ((h->db && sameString(h->db, database))
             &&  (h->chrom && sameString(h->chrom,chromName)))
                 {
                 char position[1024];
                 safef(position, sizeof position, "%s:%ld-%ld", h->chrom, h->chromStart, h->chromEnd);
@@ -5086,31 +5087,31 @@
         // Also add the side image
         theSideImg = imgBoxImageAdd(theImgBox,pngTnSide.forHtml,NULL,pixWidth, pixHeight,FALSE);
         hvgSide->rc = revCmplDisp;
         initColors(hvgSide);
         }
     }
 maybeNewFonts(hvg);
 maybeNewFonts(hvgSide);
 hvg->rc = revCmplDisp;
 initColors(hvg);
 
 /* Start up client side map. */
 hPrintf("<MAP id='map' Name=%s>\n", mapName);
 
 if (theImgBox == NULL)  // imageV2 highlighting is done by javascript. This does pdf and view-image highlight
-    highlightRegions(cart, hvg, imagePixelHeight);
+    drawHighlights(cart, hvg, imagePixelHeight);
 
 for (window=windows; window; window=window->next)
     {
     /* Find colors to draw in. */
     findTrackColors(hvg, window->trackList);
     }
 
 
 // Good to go ahead and add all imgTracks regardless of buttons, left label, centerLabel, etc.
 if (theImgBox)
     {
     if (rulerMode != tvHide)
         {
         curImgTrack = imgBoxTrackFindOrAdd(theImgBox,NULL,RULER_TRACK_NAME,rulerMode,FALSE,
                                            IMG_FIXEDPOS); // No tdb, no centerLbl, not reorderable
@@ -10577,44 +10578,44 @@
 dyStringPrintf(dy,"Mousetrap.bind('5', function() { zoomTo(500000);} ); \n");
 dyStringPrintf(dy,"Mousetrap.bind('6', function() { zoomTo(5000000);} ); \n");
 
 // buttons
 dyStringPrintf(dy,"Mousetrap.bind('c f', function() { $('input[name=\"hgTracksConfigPage\"]').submit().click() }); \n");
 dyStringPrintf(dy,"Mousetrap.bind('t s', function() { $('input[name=\"hgt_tSearch\"]').submit().click() }); \n");
 dyStringPrintf(dy,"Mousetrap.bind('h a', function() { $('input[name=\"hgt.hideAll\"]').submit().click() }); \n");
 dyStringPrintf(dy,"Mousetrap.bind('d t', function() { $('input[name=\"hgt.reset\"]').submit().click() }); \n");
 dyStringPrintf(dy,"Mousetrap.bind('d o', function() { $('input[name=\"hgt.defaultImgOrder\"]').submit().click() }); \n");
 dyStringPrintf(dy,"Mousetrap.bind('c t', function() { document.customTrackForm.submit();return false; }); \n");
 dyStringPrintf(dy,"Mousetrap.bind('t h', function() { document.trackHubForm.submit();return false; }); \n");
 dyStringPrintf(dy,"Mousetrap.bind('t c', function() { document.editHubForm.submit();return false; }); \n");
 dyStringPrintf(dy,"Mousetrap.bind('r s', function() { $('input[name=\"hgt.setWidth\"]').submit().click(); }); \n");
 dyStringPrintf(dy,"Mousetrap.bind('r f', function() { $('input[name=\"hgt.refresh\"]').submit().click() }); \n");
 dyStringPrintf(dy,"Mousetrap.bind('r v', function() { $('input[name=\"hgt.toggleRevCmplDisp\"]').submit().click() }); \n");
-dyStringPrintf(dy,"Mousetrap.bind('v d', gotoGetDnaPage); \n");
+dyStringPrintf(dy,"Mousetrap.bind('v d', function() { gotoGetDnaPage() }); \n"); // anon. function because gotoGetDnaPage is sometimes not loaded yet.
 
 // highlight
 dyStringPrintf(dy,"Mousetrap.bind('h c', function() { highlightCurrentPosition('clear'); }); \n");
 dyStringPrintf(dy,"Mousetrap.bind('h m', function() { highlightCurrentPosition('add'); }); \n");
 //dyStringPrintf(dy,"Mousetrap.bind('h n', function() { highlightCurrentPosition('new'); }); \n"); superfluos as it is just hc + hm?
 
 // focus
 dyStringPrintf(dy,"Mousetrap.bind('/', function() { $('input[name=\"hgt.positionInput\"]').focus(); return false; }, 'keydown'); \n");
-dyStringPrintf(dy,"Mousetrap.bind('?', showHotkeyHelp);\n");
+dyStringPrintf(dy,"Mousetrap.bind('?', function() { showHotkeyHelp() } );\n");
 
 // menu
 if (gotExtTools)
-    dyStringPrintf(dy,"Mousetrap.bind('s t', showExtToolDialog); \n");
+    dyStringPrintf(dy,"Mousetrap.bind('s t', function() { showExtToolDialog() } ); \n");
 
 // multi-region views
 dyStringPrintf(dy,"Mousetrap.bind('e v', function() { window.location.href='%s?%s=%s&virtModeType=exonMostly'; });  \n",
            hgTracksName(), cartSessionVarName(), cartSessionId(cart));
 dyStringPrintf(dy,"Mousetrap.bind('d v', function() { window.location.href='%s?%s=%s&virtModeType=default'; });  \n",
            hgTracksName(), cartSessionVarName(), cartSessionId(cart));
 
 dyStringPrintf(dy,"Mousetrap.bind('v s', function() { window.location.href='%s?chromInfoPage=&%s=%s'; });  \n",
            hgTracksName(), cartSessionVarName(), cartSessionId(cart));
 
 // links to a few tools
 dyStringPrintf(dy,"Mousetrap.bind('t b', function() { $('#blatMenuLink')[0].click()});\n");
 dyStringPrintf(dy,"Mousetrap.bind('t i', function() { $('#ispMenuLink')[0].click()});\n");
 dyStringPrintf(dy,"Mousetrap.bind('t t', function() { $('#tableBrowserMenuLink')[0].click()});\n");
 dyStringPrintf(dy,"Mousetrap.bind('c r', function() { $('#cartResetMenuLink')[0].click()});\n");
@@ -10921,30 +10922,35 @@
     tracksDisplay();
     }
 
 if (cartVarExists(cart, "hgt.convertChromToVirtChrom"))
     {
     cartRemove(cart, "hgt.convertChromToVirtChrom");
     return;
     }
 
 jsonObjectAdd(jsonForClient, "measureTiming", newJsonBoolean(measureTiming));
 // js code needs to know if a highlightRegion is defined for this db
 checkAddHighlight(); // call again in case tracksDisplay's call to resolvePosition changed vars
 char *highlightDef = cartOptionalString(cart, "highlight");
 if (highlightDef)
     jsonObjectAdd(jsonForClient, "highlight", newJsonString(highlightDef));
+
+char *prevColor = cartOptionalString(cart, "prevHlColor");
+if (prevColor)
+    jsonObjectAdd(jsonForClient, "prevHlColor", newJsonString(prevColor));
+
 jsonObjectAdd(jsonForClient, "enableHighlightingDialog",
 	      newJsonBoolean(cartUsualBoolean(cart, "enableHighlightingDialog", TRUE)));
 
 struct dyString *dy = dyStringNew(1024);
 jsonDyStringPrint(dy, (struct jsonElement *) jsonForClient, "hgTracks", 0);
 jsInline(dy->string);
 dyStringFree(&dy);
 
 dy = dyStringNew(1024);
 // do not have a JsonFile available when PDF/PS output
 if (enableMouseOver && isNotEmpty(mouseOverJsonFile->forCgi))
     {
     jsonWriteObjectEnd(mouseOverJson);
     /* if any data was written, it is longer than 4 bytes */
     if (strlen(mouseOverJson->dy->string) > 4)