e1ba0aaa1baec345d56cc8a518b8450c3e5d74c3
tdreszer
  Wed Jan 22 14:31:22 2014 -0800
Checking in new feature 'drag-select highlight', which was originally coded by Larry.  Redmine #709 (been on the shelf for awhile).
diff --git src/hg/js/utils.js src/hg/js/utils.js
index 3fab845..a8f1eee 100644
--- src/hg/js/utils.js
+++ src/hg/js/utils.js
@@ -893,41 +893,70 @@
 function commify (str) {
     if(typeof(str) == "number")
 	str = str + "";
     var n = str.length;
     if (n <= 3) {
 	return str;
     } else {
 	var pre = str.substring(0, n-3);
 	var post = str.substring(n-3);
 	var pre = commify(pre);
 	return pre + "," + post;
     }
 }
 
 function parsePosition(position)
-{
 // Parse chr:start-end string into a chrom, start, end object
+{
+    if (position && position.length > 0) {
         position = position.replace(/,/g, "");
         var a = /(\S+):(\d+)-(\d+)/.exec(position);
         if(a != null && a.length == 4) {
             var o = new Object();
             o.chrom = a[1];
             o.start = parseInt(a[2])
             o.end = parseInt(a[3]);
             return o;
         }
+    }
+    return null;
+}
+
+function parsePositionWithDb(position)
+// Parse db.chr:start-end string into a db, chrom, start, end object
+// Also supports be db.chr:start-end#color string
+{
+    var out = new Object();
+    var parts = position.split(".");
+    if (parts.length == 2) {
+        out.db = parts[0];
+        position = parts[1];
+    } else {
+        out.db = getDb(); // default the db 
+    }
+    parts = position.split("#"); // Highlight Region may carry its color
+    if (parts.length == 2) {
+        position = parts[0];
+        out.color = '#' + parts[1];
+    }
+    var pos = parsePosition(position);
+    if (pos != null) {
+        out.chrom = pos.chrom;
+        out.start = pos.start;
+        out.end   = pos.end;
+        return out;
+    }
     return null;
 }
 
 function getSizeFromCoordinates(position)
 {
 // Parse size out of a chr:start-end string
     var o = parsePosition(position);
     if(o != null) {
         return o.end - o.start + 1;
     }
     return null;
 }
 
 // This code is intended to allow setting up a wait cursor while waiting on the function
 var gWaitFuncArgs = [];
@@ -1057,55 +1086,43 @@
     //                return < 0 ends iteration with no call to continuingFunc
     // Both interatingFunc and continuingFunc will receive the single "args" param.
     // Hint. for multiple args, create a single struct object
 
     var ro = new _yieldingIteratorObject(function() {
             var msecs = interatingFunc(args);
             if (msecs > 0)
                 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, absolute)
+function showLoadingImage(id)
+// Show a loading image above the given id; return's id of div added (alowwing later removal).
 {
-// 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");"
-// If absolute is TRUE, then we use and absolute reference for the src tag.
     var loadingId = id + "LoadingOverlay";
-    // make an opaque overlay to partially hide the image
-    var overlay = $("<div></div>").attr("id", loadingId).css("position", "absolute");
+    var overlay = $("<div id='"+loadingId+"' class='loading'></div>");
     var ele = $(document.getElementById(id));
     overlay.appendTo("body");
-    overlay.css("top", ele.position().top);
     var divLeft = ele.position().left + 2;
-    overlay.css("left",divLeft);
-    var width = ele.width() - 5;
+    var width = ele.width() - 1;
     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;
-    var src = absolute ? "/images/loading.gif" : "../images/loading.gif";
-    $("<img src='" + src + "'/>").css("position", "relative").css('left', imgLeft).css('top', imgTop).appendTo(overlay);
+    overlay.css({top: (ele.position().top + 1) + 'px', left: divLeft + 'px'});
     return loadingId;
 }
 
 function hideLoadingImage(id)
 {
     $(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");
 }