25f258c7fdfbdf417a917fcd00fff78d698def9b
chmalee
  Fri Aug 30 12:01:24 2024 -0700
Big run through of changes to accomodate jquery 3.7.1 upgrade. Most of the changes are replacing the event methods with a change to .on(event, function(..)). A couple more changes are removing calls to jquery.type(). Also fixes various plugins and styles

diff --git src/hg/js/utils.js src/hg/js/utils.js
index c1ba2e0..e470da9 100644
--- src/hg/js/utils.js
+++ src/hg/js/utils.js
@@ -192,31 +192,31 @@
     }
     return found;
 }
 
 
 function normed(thing)
 {   // RETURNS undefined, the lone member of the set or the full set if more than one member.
     // Used for normalizing returns from jquery DOM selects (e.g. $('tr.track').children('td.data'))
     // jquery returns an "array like 'object'" with 0 or more entries.  
     // May be used on non-jquery objects and will reduce single element arrays to the element.
     // Use this to treat 0 entries the same as undefined and 1 entry as the item itself
     if (typeof(thing) === 'undefined' || thing === null
     ||  (thing.length !== undefined && thing.length === 0)  // Empty array (or 'array like object')
     ||  ($.isPlainObject(thing) && $.isEmptyObject(thing))) // Empty simple object
         return undefined;
-    if (thing.length && thing.length === 1 && jQuery.type(thing) !== 'string') // string is overkill
+    if (thing.length && thing.length === 1 && typeof thing !== 'string') // string is overkill
         return thing[0]; // Container of one item should return the item itself.
     return thing;
 }
 
 var theClient = (function() {
 // Object that detects client browser if requested              
     
     // - - - - - Private variables and/or methods - - - - - 
     var ieVersion = null;
     var browserNamed = null;
     
     // - - - - - Public methods - - - - - 
     return { // returns an object with public methods
     
         getIeVersion: function ()
@@ -998,31 +998,31 @@
         urlData[name] = val;
     });
     $(sel).filter('[name]:enabled').each(function (i) {
         var name  = $(this).attr('name');
         var val = $(this).val();
         if (name && val !== undefined && val !== null) {
             if (subtrackName && name === subtrackName) {
                 if (val === 'hide') {
                    urlData[name+"_sel"] = 0;    // Can't delete "_sel" because default takes over
                    urlData[name]        = "[]"; // Can delete vis because
                 } else {                        //     subtrack vis should be inherited.
                     urlData[name+"_sel"] = 1;
                     urlData[name]        = val;
                 }
             } else {
-                if ($.isArray( val) && val.length > 1) {
+                if (Array.isArray( val) && val.length > 1) {
                     urlData[name] = "[" + val.toString() + "]";
                 } else
                     urlData[name] = val;
             }
         }
     });
     return urlData;
 }
 
 function debugDumpFormCollection(collectionName,vars)
 { // dumps form vars collection in an alert
     var debugStr = ""; 
     for (var thisVar in vars) {
         debugStr += thisVar + "==" + vars[thisVar]+"\n";
     }
@@ -1638,65 +1638,65 @@
     // This object is for finding a subtring using tokens as bounds
     // The tokens can be literal strings or regular expressions.
     // If regular expressions are used, then only the first expression found will count
     // If not using regexp, then you can pass in limits to the original string
 
     _raw: function (begToken,endToken,someString,ixBeg,ixEnd)
     { // primitive not meant to be called directly but by bindings.inside and bindings.outside
         if (someString.length <= 0)
             return '';
         if (ixBeg === undefined || ixBeg === null)
             ixBeg = 0;
         if (ixEnd === undefined || ixEnd === null)
             ixEnd = someString.length;
         var insideBeg = ixBeg;
         var insideEnd = ixEnd;
-        if (jQuery.type(begToken) === "regexp")
+        if (begToken.constructor.name === "RegExp")
             insideBeg = someString.search(begToken);
         else if (begToken.length > 0)
             insideBeg = someString.indexOf(begToken,ixBeg);
-        if (jQuery.type(endToken) === "regexp")
+        if (endToken.constructor.name === "RegExp")
             insideEnd = someString.search(endToken);
         else if (endToken.length > 0)
             insideEnd = someString.indexOf(endToken,ixBeg);
         if (ixBeg <= insideBeg && insideBeg <= insideEnd && insideEnd <= ixEnd)
             return {start : insideBeg, stop : insideEnd};
 
         return {start : -1, stop : -1};
     },
 
     inside: function (begToken,endToken,someString,ixBeg,ixEnd)
     { // returns the inside bounds of 2 tokens within a string
     // Note ixBeg and ixEnd are optional bounds already established within string
     // Pattern match can be used instead of literal token if a regexp is passed in for the tokens
         var bounds = bindings._raw(begToken,endToken,someString,ixBeg,ixEnd);
         if (bounds.start > -1) {
-            if (jQuery.type(begToken) === "regexp")
+            if (begToken.constructor.name === "RegExp")
                 bounds.start += someString.match(begToken)[0].length;
             else
                 bounds.start += begToken.length;
         }
         return bounds;
     },
 
     outside: function (begToken,endToken,someString,ixBeg,ixEnd)
     { // returns the outside bounds of 2 tokens within a string
     // Note ixBeg and ixEnd are optional bounds already established within string
     // Pattern match can be used instead of literal token if a regexp is passed in for the tokens
         var bounds = bindings._raw(begToken,endToken,someString,ixBeg,ixEnd);
         if (bounds.start > -1) {
-            if (jQuery.type(endToken) === "regexp") 
+            if (endToken.constructor.name === "RegExp") 
                 bounds.stop  += someString.match(endToken)[0].length;
             else
                 bounds.stop  += endToken.length;
         }
         return bounds;
     },
 
     insideOut: function (begToken,endToken,someString,ixBeg,ixEnd)
     { // returns what falls between begToken and endToken as found in the string provided
     // Note ixBeg and ixEnd are optional bounds already established within string
         var bounds = bindings.inside(begToken,endToken,someString,ixBeg,ixEnd);
         if (bounds.start < bounds.stop)
             return someString.slice(bounds.start,bounds.stop);
 
         return '';
@@ -2771,31 +2771,31 @@
                 warn("sortable table's header row contains no sort columns.");
                 return;
             }
         }
         // Can wrap all columnn headers with link
         $(tr).find("th.sortable").each(function (ix) {
             if ( ! $(this).attr('onclick') ) {
                 $(this).click( function () { sortTable.sortOnButtonPress(this);} );
             }
             if (theClient.isIePre11()) { // Special case for IE since CSS :hover doesn't work
                 $(this).hover(
                     function () { $(this).css( { backgroundColor: '#CCFFCC', cursor: 'hand' } ); },
                     function () { $(this).css( { backgroundColor: '#FCECC0', cursor: '' } ); }
                 );
             }
-            if ( $(this).attr('title').length === 0) {
+            if ( $(this).attr('title') && $(this).attr('title').length === 0) {
                 var title = $(this).text().replace(/[^a-z0-9 ]/ig,'');
                 if (title.length > 0 && $(this).find('sup'))
                     title = title.replace(/[0-9]$/g,'');
                 if (title.length > 0)
                     $(this).attr('title',"Sort list on '" + title + "'." );
                 else
                     $(this).attr('title',"Sort list on column." );
             }
         });
         // Now update all of those cells
         sortTable.orderUpdate(table,sortColumns,addSuperscript);
         if ($(tbody).hasClass('initBySortOrder')) {
             sortTable.sortByColumns(tbody,sortColumns);
         }
 
@@ -3764,42 +3764,42 @@
     },
 
     mapItemMouseOut: function ()
     {
         imageV2.lastTrack = rightClick.currentMapItem; // Just a backup
         rightClick.currentMapItem = null;
     },
 
     
 
     init: function ()
     {   // Make side buttons visible (must also be called when updating rows in the imgTbl).
         var btns = $("p.btn");
         if (btns.length > 0) {
             dragReorder.zipButtons($('#imgTbl'));
-            $(btns).mouseenter( dragReorder.buttonMouseOver );
-            $(btns).mouseleave( dragReorder.buttonMouseOut  );
+            $(btns).on("mouseenter", dragReorder.buttonMouseOver );
+            $(btns).on("mouseleave", dragReorder.buttonMouseOut  );
             $(btns).show();
         }
         var handle = $("td.dragHandle");
         if (handle.length > 0) {
-            $(handle).mouseenter( dragReorder.dragHandleMouseOver );
-            $(handle).mouseleave( dragReorder.dragHandleMouseOut  );
+            $(handle).on("mouseenter", dragReorder.dragHandleMouseOver );
+            $(handle).on("mouseleave", dragReorder.dragHandleMouseOut  );
         }
 
         // setup mouse callbacks for the area tags
-        $("#imgTbl").find("tr").mouseover( dragReorder.trMouseOver );
+        $("#imgTbl").find("tr").on("mouseover", dragReorder.trMouseOver );
         $("#imgTbl").find("tr").each( function (i, row) {
             // save the original y positions of each row
             //if (row.id in dragReorder.originalHeights === false) {
                 dragReorder.originalHeights[row.id] = row.getBoundingClientRect().y + window.scrollY;
             //}
         });
 
 
         $(".area").each( function(t) {
                             this.onmouseover = dragReorder.mapItemMouseOver;
                             this.onmouseout = dragReorder.mapItemMouseOut;
                             this.onclick = posting.mapClk;
                         });
     }
 };