7711814fb6a160f9a72282a301415db91665d810
tdreszer
  Wed Aug 17 15:55:30 2011 -0700
Larry and I have added page/image refresh when it is dirty.  This is for solving the main back-button issue, where js/ajax changes to the image are lost when using back-button.
diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index 44176f9..7942a53 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -24,38 +24,70 @@
 var inPlaceUpdate = false;     // modified based on value of hgTracks.inPlaceUpdate and mapIsUpdateable
 var contextMenu;
 
 /* Data passed in from CGI via the hgTracks object:
  *
  * string chromName           // current chromosome
  * int winStart               // genomic start coordinate (0-based, half-open)
  * int winEnd                 // genomic end coordinate
  * int newWinWidth            // new width if user clicks on the top ruler (in bps)
  * boolean dragSelection      // true if we should allow drag and select
  * boolean revCmplDisp        // true if we are in reverse display
  * int insideX                // width of side-bar (in pixels)
  * int rulerClickHeight       // height of ruler (in pixels)
  */
 
-function initVars(img)
+function initVars()
 {
 // There are various entry points, so we call initVars in several places to make sure this variables get updated.
     if(!originalPosition) {
         // remember initial position and size so we can restore it if user cancels
         originalPosition = getOriginalPosition();
         originalSize = $('#size').text();
         originalCursor = jQuery('body').css('cursor');
+
+        jQuery.each(jQuery.browser, function(i, val) {
+            if(val) {
+                browser = i;
+            }
+            });
+        // jQuery load function with stuff to support drag selection in track img
+        if(browser == "safari") {
+            if(navigator.userAgent.indexOf("Chrome") != -1) {
+            // Handle the fact that (as of 1.3.1), jQuery.browser reports "safari" when the browser is in fact Chrome.
+            browser = "chrome";
+            } else {
+                // Safari has the following bug: if we update the hgTracks map dynamically, the browser ignores the changes (even
+                // though if you look in the DOM the changes are there). So we have to do a full form submission when the
+                // user changes visibility settings or track configuration.
+                // As of 5.0.4 (7533.20.27) this is problem still exists in safari.
+                // As of 5.1 (7534.50) this problem appears to have been fixed - unfortunately, logs for 7/2011 show vast majority of safari users
+                // are pre-5.1 (5.0.5 is by far the most common).
+                //
+                // Early versions of Chrome had this problem too, but this problem went away as of Chrome 5.0.335.1 (or possibly earlier).
+                mapIsUpdateable = false;
+                var reg = new RegExp("Version\/(\[0-9]+\.\[0-9]+) Safari");
+                var a = reg.exec(navigator.userAgent);
+                if(a && a[1]) {
+                    var version = Number(a[1]);
+                    if(version >= 5.1) {
+                        mapIsUpdateable = true;
+                    }
+                }
+            }
+        }
+        inPlaceUpdate = hgTracks.inPlaceUpdate && mapIsUpdateable;
     }
 }
 
 function selectStart(img, selection)
 {
     initVars();
     if(contextMenu) {
         contextMenu.hide();
     }
     var now = new Date();
     startDragZoom = now.getTime();
     blockUseMap = true;
     // vvvvvvv Should be obsolete since maps items are ignored when startDragZoom is set
 //    if(imageV2 == false) {
 //        jQuery.each(jQuery.browser, function(i, val) {
@@ -97,46 +129,66 @@
 function getPosition()
 {
 // Return current value of position box
     var ele = getPositionElement();
     if(ele != null) {
 	return ele.value;
     }
     return null;
 }
 
 function getOriginalPosition()
 {
     return originalPosition || getPosition();
 }
 
+function markAsDirtyPage()
+{ // Page is marked as dirty so that the backbutton can be overridden
+    var dirty = $('#dirty');
+    if (dirty != undefined && dirty.length != 0)
+        $(dirty).val('yes');
+}
+
+function isDirtyPage()
+{ // returns true if page was marked as dirty
+  // This will allow the backbutton to be overridden
+
+    var dirty = $('#dirty');
+    if (dirty != undefined && dirty.length > 0) {
+        if ($(dirty).val() == 'yes')
+            return true;
+    }
+    return false;
+}
+
 function setPosition(position, size)
 {
 // Set value of position and size (in hiddens and input elements).
 // We assume size has already been commified.
 // Either position or size may be null.
     if(position) {
         // There are multiple tags with name == "position" (one in TrackHeaderForm and another in TrackForm).
 	var tags = document.getElementsByName("position");
 	for (var i = 0; i < tags.length; i++) {
 	    var ele = tags[i];
 	    ele.value = position;
 	}
     }
     if(size) {
         $('#size').text(size);
     }
+    markAsDirtyPage();
 }
 
 function checkPosition(img, selection)
 {
 // return true if user's selection is still w/n the img (including some slop).
     var imgWidth = jQuery(img).width();
     var imgHeight = jQuery(img).height();
     var imgOfs = jQuery(img).offset();
     var slop = 10;
 
     // We ignore clicks in the gray tab and track title column (we really should suppress all drag activity there,
     // but I don't know how to do that with imgAreaSelect).
     var leftX = hgTracks.revCmplDisp ? imgOfs.left - slop : imgOfs.left + hgTracks.insideX - slop;
     var rightX = hgTracks.revCmplDisp ? imgOfs.left + imgWidth - hgTracks.insideX + slop : imgOfs.left + imgWidth + slop;
 
@@ -239,57 +291,32 @@
 //            $('#map').append(mapHtml);
 //        }
     }
 //    mapHtml = null;
     startDragZoom = null;
     setTimeout('blockUseMap=false;',50); // Necessary incase the selectEnd was over a map item. select takes precedence.
     return true;
 }
 
 $(window).load(function () {
     jQuery.each(jQuery.browser, function(i, val) {
         if(val) {
             browser = i;
         }
         });
-    // jQuery load function with stuff to support drag selection in track img
-    if(browser == "safari") {
-        if(navigator.userAgent.indexOf("Chrome") != -1) {
-        // Handle the fact that (as of 1.3.1), jQuery.browser reports "safari" when the browser is in fact Chrome.
-        browser = "chrome";
-        } else {
-            // Safari has the following bug: if we update the hgTracks map dynamically, the browser ignores the changes (even
-            // though if you look in the DOM the changes are there). So we have to do a full form submission when the
-            // user changes visibility settings or track configuration.
-            // As of 5.0.4 (7533.20.27) this is problem still exists in safari.
-            // As of 5.1 (7534.50) this problem appears to have been fixed - unfortunately, logs for 7/2011 show vast majority of safari users
-            // are pre-5.1 (5.0.5 is by far the most common).
-            //
-            // Early versions of Chrome had this problem too, but this problem went away as of Chrome 5.0.335.1 (or possibly earlier).
-            mapIsUpdateable = false;
-            var reg = new RegExp("Version\/(\[0-9]+\.\[0-9]+) Safari");
-            var a = reg.exec(navigator.userAgent);
-            if(a && a[1]) {
-                var version = Number(a[1]);
-                if(version >= 5.1) {
-                    mapIsUpdateable = true;
-                }
-            }
-        }
-    }
+    initVars();
 
-    inPlaceUpdate = hgTracks.inPlaceUpdate && mapIsUpdateable;
     loadImgAreaSelect(true);
     if($('#hgTrackUiDialog'))
         $('#hgTrackUiDialog').hide();
 
     // Don't load contextMenu if jquery.contextmenu.js hasn't been loaded
     if(trackImg && jQuery.fn.contextMenu) {
         $('#hgTrackUiDialog').hide();
         if(imageV2) {
             $("map[name!=ideoMap]").each( function(t) { parseMap($(this,false));});
         } else {
             // XXXX still under debate whether we have to remove the map
             parseMap($('#map'),true);
             $('#map').empty();
         }
 
@@ -707,30 +734,31 @@
 function imgTblSetOrder(table)
 {
 // Sets the 'order' value for the image table after a drag reorder
     var names = [];
     var values = [];
     $("tr.imgOrd").each(function (i) {
         if ($(this).attr('abbr') != $(this).attr('rowIndex').toString()) {
             $(this).attr('abbr',$(this).attr('rowIndex').toString());
             var name = this.id.substring('tr_'.length) + '_imgOrd';
             names.push(name);
             values.push($(this).attr('abbr'));
         }
     });
     if(names.length > 0) {
         setCartVars(names,values);
+        markAsDirtyPage();
     }
 }
 
 function imgTblTrackShowCenterLabel(tr, show)
 {   // Will show or hide centerlabel as requested
     // adjust button, sideLabel height, sideLabelOffset and centerlabel display
 
     if(!$(tr).hasClass('clOpt'))
         return;
     var center = $(tr).find(".sliceDiv.cntrLab");
     if($(center) == undefined)
         return;
     seen = ($(center).css('display') != 'none');
     if(show == seen)
         return;
@@ -979,45 +1007,46 @@
     if ( $(this).is("img") ) {
         pan = $(this).parent("div");
         pic = $(this);
     }
     else if ( $(this).is("div.scroller")  ) {
         pan = $(this);
         pic = $(this).children("img#panImg"); // Get the real pic
     }
 
     if(pan == undefined || pic == undefined) {
         throw "Not a div with a child image! 'panImages' can only be used with divs contain images.";
     }
 
     // globals across all panImages
     portalWidth     = $(pan).width();
-    panAdjustHeight(prevX);
     // globals to one panImage
     var newX        = 0;
     var mouseDownX  = 0;
     var mouseIsDown = false;
     var beyondImage = false;
     var atEdge      = false;
 
     initialize();
 
     function initialize(){
 
         if ( !($.browser.msie) ) // IE will override map items cursors as well!
             $(pan).parents('td.tdData').css('cursor',"url(../images/grabber.cur),w-resize");
 
+        panAdjustHeight(prevX);
+
         pan.mousedown(function(e){
              if (e.which > 1 || e.button > 1 || e.shiftKey)
                  return true;
             if(mouseIsDown == false) {
                 if(contextMenu) {
                     contextMenu.hide();
                 }
                 mouseIsDown = true;
                 mouseDownX = e.clientX;
                 atEdge = (!beyondImage && (prevX >= leftLimit || prevX <= rightLimit));
                 $(document).bind('mousemove',panner);
                 $(document).bind( 'mouseup', panMouseUp);  // Will exec only once
                 return false;
             }
         });
@@ -1343,30 +1372,43 @@
     }
     var thisForm=$(obj).parents('form');
     if(thisForm == undefined || $(thisForm).length == 0)
         thisForm=$("FORM");
     if($(thisForm).length > 1 )
         thisForm=$(thisForm)[0];
     if(thisForm != undefined && $(thisForm).length == 1) {
         //alert("posting form:"+$(thisForm).attr('name'));
         return postTheForm($(thisForm).attr('name'),obj.href);
     }
     return true;
 }
 
 $(document).ready(function()
 {
+    // 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.
+    initVars();
+    if (isDirtyPage()) {
+        jQuery('body').css('cursor', 'wait');
+        if(inPlaceUpdate)
+            navigateInPlace("", null);
+        else {
+            window.location = "../cgi-bin/hgTracks?hgsid=" + getHgsid();
+            return false;
+        }
+    }
     var db = getDb();
     if(jQuery.fn.autocomplete && $('input#suggest') && db) {
         if(newJQuery) {
             $('input#suggest').autocomplete({
                                                 delay: 500,
                                                 minLength: 2,
                                                 source: ajaxGet(function () {return db;}, new Object, true),
                                                 open: function(event, ui) {
                                                     var pos = $(this).offset().top + $(this).height();
                                                     if (!isNaN(pos)) {
                                                         var maxHeight = $(window).height() - pos - 30;  // take off a little more because IE needs it
                                                         var auto = $('.ui-autocomplete');
                                                         var curHeight = $(auto).children().length * 21;
                                                         if (curHeight > maxHeight)
                                                             $(auto).css({maxHeight: maxHeight+'px',overflow:'scroll'});
@@ -1387,44 +1429,44 @@
                                                 delay: 500,
                                                 minchars: 2,
                                                 ajax_get: ajaxGet(function () {return db;}, new Object, false),
                                                 callback: function (obj) {
                                                     setPosition(obj.id, commify(getSizeFromCoordinates(obj.id)));
                                                     makeSureSuggestTrackIsVisible();
                                                     // jQuery('body').css('cursor', 'wait');
                                                     // document.TrackHeaderForm.submit();
                                                 }
                                             });
         }
         // I want to set focus to the suggest element, but unforunately that prevents PgUp/PgDn from
         // working, which is a major annoyance.
         // $('input#suggest').focus();
     }
-    initVars();
 
     if(jQuery.jStore) {
         // Experimental (currently dead) code to handle "user hits back button" problem.
         if(false) {
             jQuery.extend(jQuery.jStore.defaults, {
                               project: 'hgTracks',
                               engine: 'flash',
                               flash: '/jStore.Flash.html'
                           });
         }
         jQuery.jStore.load();
     }
 
+
     // Convert map AREA gets to post the form, ensuring that cart variables are kept up to date (but turn this off for search form).
     if($("FORM").length > 0 && $('#trackSearch').length == 0) {
         var allLinks = $('a');
         $( allLinks ).unbind('click');
         $( allLinks ).click( postToSaveSettings );
     }
     if($('#pdfLink').length == 1) {
         $('#pdfLink').click(function(i) {
             var thisForm=$('#TrackForm');
             if(thisForm != undefined && $(thisForm).length == 1) {
                 //alert("posting form:"+$(thisForm).attr('name'));
                 updateOrMakeNamedVariable($(thisForm),'hgt.psOutput','on');
                 return postTheForm($(thisForm).attr('name'),this.href);
             }
             return true;
@@ -2533,30 +2575,31 @@
 {
 // Reload various UI widgets after updating imgTbl map.
     parseMap(null, true);
     $("map[name!=ideoMap]").each( function(t) { parseMap($(this, false));});
     initImgTblButtons();
     loadImgAreaSelect(false);
     // Do NOT reload context menu (otherwise we get the "context menu sticks" problem).
     // loadContextMenu($('#tr_' + id));
     if(trackImgTbl.tableDnDUpdate)
         trackImgTbl.tableDnDUpdate();
     reloadFloatingItem();
     // Turn on drag scrolling.
     if(hgTracks.imgBoxPortal) {
         $("div.scroller").panImages();
     }
+    markAsDirtyPage();
 }
 
 function updateTrackImgForId(html, id)
 {
 // update row in imgTbl for given id.
 // return true if we successfully pull slice for id and update it in imgTrack.
     var str = "<TR id='tr_" + id + "'[^>]*>([\\s\\S]+?)</TR>";
     var reg = new RegExp(str);
     var a = reg.exec(html);
     if(a && a[1]) {
         var tr = $('#tr_' + id);
         $(tr).html(a[1]);
         // NOTE: Want to examine the png? Uncomment:
         //var img = $('#tr_' + id).find("img[id^='img_data_']").attr('src');
         //warn("Just parsed image:<BR>"+img);