af3a143571e5aa064eab75c34f9444b35413b562
chmalee
  Tue Nov 30 15:28:15 2021 -0800
Add snippet support to trix searching. Required changing the
wordPos from the first highest matching wordIndex to the
wordIndex of the actual span. Have trixContextIndex create a
second level index for fast retrieval of line offsets in
original text file used by ixIxx. Create a simple UI for navigating
hgFind search results.

diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index c74aed6..f13c08e 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -4489,30 +4489,43 @@
                 var url = "../cgi-bin/hgTracks?position=" + newPos + "&" + cart.varsToUrlData({ 'db': getDb(), 'hgsid': getHgsid() });
                 window.location.assign(url);
                 return false;
             }
 
             // redirect to hgBlat if the input looks like a DNA sequence
             // minimum length=19 so we do not accidentally redirect to hgBlat for a gene identifier 
             // like ATG5
             var dnaRe = new RegExp("^(>[^\n\r ]+[\n\r ]+)?(\\s*[actgnACTGN \n\r]{19,}\\s*)$");
             if (dnaRe.test(newPos)) {
                 var blatUrl = "hgBlat?type=BLAT%27s+guess&userSeq="+newPos;
                 window.location.href = blatUrl;
                 return false;
             }
 
+            // redirect to search disambiguation page if it looks like we didn't enter a regular position:
+            var canonMatch = newPos.match(canonicalRangeExp);
+            var gbrowserMatch = newPos.match(gbrowserRangeExp);
+            var lengthMatch = newPos.match(lengthRangeExp);
+            var bedMatch = newPos.match(bedRangeExp);
+            var sqlMatch = newPos.match(sqlRangeExp);
+            var singleMatch = newPos.match(singleBaseExp);
+            var positionMatch = canonMatch || gbrowserMatch || lengthMatch || bedMatch || sqlMatch || singleMatch;
+            if (positionMatch === null) {
+                window.location.assign("../cgi-bin/searchExample?hgsid=" + getHgsid() + "&search=" + newPos);
+                return false;
+            }
+                
             return true;
         });
         // Have vis box changes update cart through ajax.  This helps keep page/cart in sync.
         vis.initForAjax();
 
         // We reach here from these possible paths:
         // A) Forward: Full page retrieval: hgTracks is first navigated to (or chrom change)
         // B) Back-button past a full retrieval (B in: ->A,->b,->c(full page),->d,<-c,<-B(again))
         //    B1) Dirty page: at least one non-position change (e.g. 1 track vis changed in b)
         //    B2) Clean page: only position changes from A->b->| 
         var curPos = encodeURIComponent(genomePos.get().replace(/,/g,''));
         var curDbPos = hgTracks.lastDbPos;
         var cachedPos = imageV2.history.getState().data.position;
         var cachedDbPos = imageV2.history.getState().data.lastDbPos;
         // A) Forward: Full page retrieval: hgTracks is first navigated to (or chrom change)
@@ -5081,30 +5094,31 @@
     });
 
     // The page may be reached via browser history (back button)
     // If so, then this code should detect if the image has been changed via js/ajax
     // and will reload the image if necessary.
     // NOTE: this is needed for IE but other browsers can detect the dirty page much earlier
     if (!imageV2.backSupport) {
         if (imageV2.isDirtyPage()) {
             // mark as non dirty to avoid infinite loop in chrome.
             imageV2.markAsCleanPage();
             jQuery('body').css('cursor', 'wait');
             window.location = "../cgi-bin/hgTracks?hgsid=" + getHgsid();
             return false;
         }
     }
+
     initVars();
     imageV2.loadSuggestBox();
     if ($('#pdfLink').length === 1) {
         $('#pdfLink').click(function(i) {
             var thisForm = normed($('#TrackForm'));
             if (thisForm) {
                 //alert("posting form:"+$(thisForm).attr('name'));
                 updateOrMakeNamedVariable($(thisForm),'hgt.psOutput','on');
                 return postTheForm($(thisForm).attr('name'),this.href);
             }
             return true;
         });
     }
 
     if (imageV2.enabled) {