cc1314a4ff21d4dc406d4ae239566dfa9d0c6fae
larrym
  Wed Nov 2 14:03:29 2011 -0700
replace some instances of $(#...) with document.getElementById to deal with possible metacharacter in track names; add and use escapeJQuerySelectorChars
diff --git src/hg/js/utils.js src/hg/js/utils.js
index aa521ad..e71e2f2 100644
--- src/hg/js/utils.js
+++ src/hg/js/utils.js
@@ -1048,51 +1048,52 @@
                 ro.step(msecs,args);      // recursion
             else if (msecs == 0)
                 continuingFunc(args);     // completion
             // else (msec < 0) // abandon
         });
     ro.step(1,args);                      // kick-off
 }
 
 function showLoadingImage(id)
 {
 // Show a loading image above the given id; return's id of div added (so it can be removed when loading is finished).
 // This code was mostly directly copied from hgHeatmap.js, except I also added the "overlay.appendTo("body");"
     var loadingId = id + "LoadingOverlay";
     // make an opaque overlay to partially hide the image
     var overlay = $("<div></div>").attr("id", loadingId).css("position", "absolute");
+    var ele = $(document.getElementById(id));
     overlay.appendTo("body");
-    overlay.css("top", $('#'+ id).position().top);
-    var divLeft = $('#'+ id).position().left + 2;
+    overlay.css("top", ele.position().top);
+    var divLeft = ele.position().left + 2;
     overlay.css("left",divLeft);
-    var width = $('#'+ id).width() - 5;
-    var height = $('#'+ id).height();
+    var width = ele.width() - 5;
+    var height = ele.height();
     overlay.width(width);
     overlay.height(height);
     overlay.css("background", "white");
     overlay.css("opacity", 0.75);
     // now add the overlay image itself in the center of the overlay.
     var imgWidth = 220;   // hardwired based on width of loading.gif
     var imgLeft = (width / 2) - (imgWidth / 2);
     var imgTop = (height / 2 ) - 10;
     $("<img src='../images/loading.gif'/>").css("position", "relative").css('left', imgLeft).css('top', imgTop).appendTo(overlay);
     return loadingId;
 }
 
 function hideLoadingImage(id)
 {
-    $('#' + id).remove();
+    $(document.getElementById(id)).remove();
 }
 
 function codonColoringChanged(name)
 {
 // Updated disabled state of codonNumbering checkbox based on current value of track coloring select.
     var val = $("select[name='" + name + ".baseColorDrawOpt'] option:selected").text();
     $("input[name='" + name + ".codonNumbering']").attr('disabled', val == "OFF");
 }
 
 
 //////////// Drag and Drop ////////////
 function tableDragAndDropRegister(thisTable)
 {// Initialize a table with tableWithDragAndDrop
     if ($(thisTable).hasClass("tableWithDragAndDrop") == false)
         return;
@@ -2621,15 +2622,20 @@
             $(this).removeClass('excluded'); // remove .excluded from matching
         else
             $(this).addClass('excluded');    // add .excluded" to non-matching
     });
 
     // If all options except "all" are included then all should nt be excluded
     var excluded = $(filter).children('option.excluded');
     if (excluded.length == 1) {
         var text = $(excluded[0]).text();
         if (text == 'All' || text == 'Any')
             $(excluded[0]).removeClass('excluded');
     }
     return true;
 }
 
+function escapeJQuerySelectorChars(str)
+{
+    // replace characters which are reserved in jQuery selectors (surprisingly jQuery does not have a built in function to do this).
+    return str.replace(/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~"])/g,'\\$1');
+}