4c35906f3295ddfde3842bce49b4573c1ff0c446
tdreszer
  Thu Dec 22 13:20:42 2011 -0800
Massive sorts on IE9 were still dying, until I replaced using 'sorting' class with 'showLoadingImage()'.  The loading image eliminateates redrawing on every little change.
diff --git src/hg/js/utils.js src/hg/js/utils.js
index f947586..44b272f 100644
--- src/hg/js/utils.js
+++ src/hg/js/utils.js
@@ -929,32 +929,32 @@
         $(waitMask).hide();
 }
 
 function waitMaskSetup(timeOutInMs)
 { // Sets up the waitMask to block page manipulation until cleared
 
     // Find or create the waitMask (which masks the whole page)
     var  waitMask = $('#waitMask');
     if( waitMask == undefined || waitMask.length != 1) {
         // create the waitMask
         $("body").append("<div id='waitMask' class='waitMask');'></div>");
         waitMask = $('#waitMask');
     }
     $(waitMask).css({opacity:0.0,display:'block',top: '0px', height: $(document).height().toString() + 'px' });
     // Special for IE, since it takes so long, make mask obvious
-    if ($.browser.msie)
-        $(waitMask).css({opacity:0.4,backgroundColor:'gray'});
+    //if ($.browser.msie)
+    //    $(waitMask).css({opacity:0.4,backgroundColor:'gray'});
 
     // Things could fail, so always have a timeout.
     if(timeOutInMs == undefined || timeOutInMs ==0)
         timeOutInMs = 30000; // IE can take forever!
 
     if (timeOutInMs > 0)
         setTimeout('waitMaskClear();',timeOutInMs); // Just in case
 
     return waitMask;  // The caller could add css if they wanted.
 }
 
 function _launchWaitOnFunction()
 { // should ONLY be called by waitOnFunction()
   // Launches the saved function
     var func = gWaitFunc;
@@ -1286,30 +1286,31 @@
     //       A reason to preserve the order in the cart is if the order will affect other cgis.  For instance: sort subtracks and see that order in the hgTracks image.
 
     // Sorting a table by columns relies upon the columns obj, whose C equivalent would look like:
     //struct column
     //    {
     //    char *  tags[];     // a list of field names in sort order (e.g. 'cell', 'shortLabel')
     //    boolean reverse[];  // the sort direction for each sort field
     //    int     cellIxs[];  // The indexes of the columns in the table to be sorted
     //    boolean useAbbr[];  // Compare on Abbr or on text()?
     //    };
 
     // These 2 globals are used during setTimeout, so that rows can be hidden while sorting
     // and javascript timeout on slow (IE) browsers is less likely
     columns: null,
     tbody: null,
+    loadingId: null,
 
     row: function (tr,sortColumns,row)  // UNUSED: sortTable.fieldCmp works fine
     {
         this.fields  = new Array();
         this.reverse = new Array();
         this.row     = row;
         for(var ix=0;ix<sortColumns.cellIxs.length;ix++)
             {
             var th = tr.cells[sortColumns.cellIxs[ix]];
             this.fields[ix]  = (sortColumns.useAbbr[ix] ? th.abbr : $(th).text()).toLowerCase(); // case insensitive sorts
             this.reverse[ix] = sortColumns.reverse[ix];
             }
     },
 
     rowCmp: function (a,b)  // UNUSED: sortTable.fieldCmp works fine
@@ -1350,57 +1351,64 @@
 
         // Create array of the primary sort column's text
         var cols = new Array();
         var trs = tbody.rows;
         $(trs).each(function(ix) {
             var th = this.cells[sortColumns.cellIxs[0]];
             if(sortColumns.useAbbr[0])
                 cols.push(new sortTable.field(th.abbr,sortColumns.reverse[0],this));
             else
                 cols.push(new sortTable.field($(th).text(),sortColumns.reverse[0],this));
         });
 
         // Sort the array
         cols.sort(sortTable.fieldCmp);
 
-        for(var cIx=0;cIx<cols.length;cIx++) {
-            tbody.appendChild(cols[cIx].row);
-        }
+        // most efficient reload of sorted rows I have found
+        var sortedRows = jQuery.map(cols, function(col, i) { return col.row; });
+        $(tbody).append( sortedRows );
 
         sortTable.tbody=tbody;
         sortTable.columns=sortColumns;
         setTimeout('sortTable.sortFinish(sortTable.tbody,sortTable.columns)',5); // Avoid javascript timeouts!
     },
 
     sortFinish: function (tbody,sortColumns)
     {// Additional sort cleanup.
     // This is in a separate function to allow calling with setTimeout() which will prevent javascript timeouts (I hope)
         sortTable.savePositions(tbody);
         if ($(tbody).hasClass('altColors'))
             sortTable.alternateColors(tbody,sortColumns);
         $(tbody).parents("table.tableWithDragAndDrop").each(function (ix) {
             tableDragAndDropRegister(this);
         });
-        //$(tbody).show();
-        $(tbody).removeClass('sorting');
+        if (sortTable.loadingId != null)
+            hideLoadingImage(sortTable.loadingId);
     },
 
     sortByColumns: function (tbody,sortColumns)
     {// Will sort the table based on the abbr values on a set of <TH> colIds
     // Expects tbody to not sort thead, but could take table
-        //$(tbody).hide();
-        $(tbody).addClass('sorting');
+
+        // Used to use 'sorting' class, but showLoadingImage results in much less screen redrawing
+        // For IE especially this was the difference between dead/timedout scripts and working sorts!
+        var id = $(tbody).attr('id');
+        if (id == undefined || id.length == 0) {
+            $(tbody).attr('id',"tbodySort"); // Must have some id!
+            id = $(tbody).attr('id');
+        }
+        sortTable.loadingId = showLoadingImage(id);
         sortTable.tbody=tbody;
         sortTable.columns=sortColumns;
         setTimeout('sortTable.sort(sortTable.tbody,sortTable.columns)',50); // This allows hiding the rows while sorting!
     },
 
     trAlternateColors: function (tbody,rowGroup,cellIx)
     {// Will alternate colors for visible table rows.
     // If cellIx(s) provided then color changes when the column(s) abbr or els innerHtml changes
     // If no cellIx is provided then alternates on rowGroup (5= change color 5,10,15,...)
     // Expects tbody to not color thead, but could take table
         var darker   = false; // == false will trigger first row to be change color = darker
 
         if (arguments.length<3) { // No columns to check so alternate on rowGroup
 
             if (rowGroup == undefined || rowGroup == 0)