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))