db7abbec917941788e455d6d3d1f0a2e9d05a7c1
tdreszer
  Mon Jun 23 13:15:02 2014 -0700
When there are too many tracks, image only reload is slower than full page reload.  Now there is a cut-off of 50 tracks, above which only full page reloads will be done.  Redmine #13347.
diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index 708398c..0d98e54 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -2892,30 +2892,37 @@
         var dirty = normed($('#dirty'));
         if (dirty)
             $(dirty).val('false');
     },
 
     isDirtyPage: function ()
     { // returns true if page was marked as dirty
     // This will allow the backbutton to be overridden
 
         var dirty = normed($('#dirty'));
         if (dirty && $(dirty).val() === 'true')
             return true;
         return false;
     },
     
+    manyTracks: function ()
+    {   // image-reload is slower than whole page reload when there are too many tracks
+        if (!hgTracks || !hgTracks.trackDb || objKeyCount(hgTracks.trackDb) > 50)
+            return true;
+        return false;
+    },
+
     updateTiming: function (response)
     {   // update measureTiming text on current page based on what's in the response
         var reg = new RegExp("(<span class='timing'>.+?</span>)", "g");
         var strs = [];
         for (var a = reg.exec(response); a && a[1]; a = reg.exec(response)) {
             strs.push(a[1]);
         }
         if (strs.length > 0) {
             $('.timing').remove();
             for (var ix = strs.length; ix > 0; ix--) {
                 $('body').prepend(strs[ix - 1]);
             }
         }
         reg = new RegExp("(<span class='trackTiming'>[\\S\\s]+?</span>)");
         a = reg.exec(response);
@@ -3116,37 +3123,47 @@
                     type: getOrPost,
                     url: "../cgi-bin/hgTracks",
                     data: cart.addUpdatesToUrl(data),
                     dataType: "html",
                     trueSuccess: imageV2.updateImgAndMap,
                     success: catchErrorOrDispatch,
                     error: errorHandler,
                     cmd: 'refresh',
                     loadingId: loadingId,
                     id: trackName,
                     newVisibility: newVisibility,
                     cache: false
                 });
     },
 
-    fullReload: function()
+    fullReload: function(extraData)
     {
         // force reload of whole page via trackform submit
         // This function does not return
         jQuery('body').css('cursor', 'wait');
+        if (extraData || cart.updatesWaiting()) {
+            var url = cart.addUpdatesToUrl(window.location.href);
+            if (extraData) {
+                if ( url.lastIndexOf("?") === -1)
+                    url += "?" + extraData;
+                else
+                    url += '&' + extraData;
+            }
+            window.location.assign(url);
+            return false;
+        }
         document.TrackHeaderForm.submit();
-
     },
 
     updateImgAndMap: function (response, status)
     {   // Handle ajax response with an updated trackMap image, map and optional ideogram.
         //
         // this.cmd can be used to figure out which menu item triggered this.
         // this.id === appropriate track if we are retrieving just a single track.
 
         // update local hgTracks.trackDb to reflect possible side-effects of ajax request.
         var newJson = scrapeVariable(response, "hgTracks");
         var oldJson = hgTracks;
         var valid = false;
         if (!newJson) {
             var stripped = {};
             stripJsEmbedded(response, true, stripped);
@@ -3338,30 +3355,36 @@
             }
             return false;
         } else {
             return true;
         }
     },
 
     navigateInPlace: function (params, disabledEle, keepCurrentTrackVisible)
     {   // request an hgTracks image, using params
         // disabledEle is optional; this element will be enabled when update is complete
         // If keepCurrentTrackVisible is true, we try to maintain relative position of the item
         // under the mouse after the in-place update.
         // Tim thinks we should consider disabling all UI input while we are doing in-place update.
         // TODO: waitOnFuction?
     
+        // No ajax image update if there are too many tracks!
+        if (imageV2.manyTracks()) {
+            imageV2.fullReload(params);
+            return false;  // Shouldn't return from fullReload but I have seen it in FF
+        }
+    
         // If UCSC Genes (or any suggestion) is supposed to be made visible, then do so
         if ($("#suggestTrack").length && $('#hgFindMatches').length)
             vis.makeTrackVisible($("#suggestTrack").val());
 
         jQuery('body').css('cursor', 'wait');
         var currentId, currentIdYOffset;
         if (keepCurrentTrackVisible) {
             var item = rightClick.currentMapItem || imageV2.lastTrack;
             if (item) {
                 var top = $(document.getElementById("tr_" + item.id)).position().top;
                 if (top >= $(window).scrollTop()
                 || top < $(window).scrollTop() + $(window).height()) {
                     // don't bother if the item is not currently visible.
                     currentId = item.id;
                     currentIdYOffset = top - $(window).scrollTop();
@@ -3465,40 +3488,42 @@
         imageV2.history.Adapter.bind(window,'statechange',function(){
             var prevPos = imageV2.history.getState().data.position;
             var curPos = encodeURIComponent(genomePos.get().replace(/,/g,''));
             if (prevPos && prevPos !== curPos) {
                 // NOTE: this function is NOT called when backing passed a full retrieval boundary
                 genomePos.set(decodeURIComponent(prevPos));
                 imageV2.navigateInPlace("position=" + prevPos, null, false);
             }
         });
         
         // TODO: move elsewhere?
         // With history support it is best that most position changes will ajax-update the image
         // This ensures that the 'go' and 'refresh' button will do so unless the chrom changes.
         $("input[value='go'],input[value='refresh']").click(function () {
             var newPos = genomePos.get().replace(/,/g,'');
+            if ( ! imageV2.manyTracks() ) {
                 var newChrom = newPos.split(':')[0];
                 var oldChrom  = genomePos.getOriginalPos().split(':')[0];
                 if (newChrom === oldChrom) {
                     imageV2.markAsDirtyPage();
                     imageV2.navigateInPlace("position="+encodeURIComponent(newPos), null, false);
                     window.scrollTo(0,0);
                     return false;
                 }
+            }
             
-            // If chrom changed AND there are vis updates waiting...
+            // If not just image update AND there are vis updates waiting...
             if (cart.updatesWaiting()) {
                 var url = "../cgi-bin/hgTracks?" + cart.varsToUrlData({ 'db': getDb(), 
                                                         'position': newPos, 'hgsid': getHgsid() });
                 window.location.assign(url);
                 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))