src/hg/js/hgTracks.js 1.49
1.49 2009/12/29 20:24:53 larrym
handle changes to track buttons
Index: src/hg/js/hgTracks.js
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/js/hgTracks.js,v
retrieving revision 1.48
retrieving revision 1.49
diff -b -B -U 4 -r1.48 -r1.49
--- src/hg/js/hgTracks.js 9 Dec 2009 03:31:09 -0000 1.48
+++ src/hg/js/hgTracks.js 29 Dec 2009 20:24:53 -0000 1.49
@@ -18,9 +18,9 @@
var trackImgTbl; // jQuery element used for image table under imageV2
var imgAreaSelect; // jQuery element used for imgAreaSelect
var originalImgTitle;
var autoHideSetting = true; // Current state of imgAreaSelect autoHide setting
-var selectedMapItem; // index of currently choosen map item (via context menu).
+var selectedMenuItem; // currently choosen context menu item (via context menu).
var browser; // browser ("msie", "safari" etc.)
function commify (str) {
if(typeof(str) == "number")
@@ -40,9 +40,9 @@
{
// 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 = $('#positionHidden').val();
+ originalPosition = $('#positionHidden').val() || getPosition();
originalSize = $('#size').text();
originalCursor = jQuery('body').css('cursor');
}
}
@@ -75,8 +75,23 @@
setPosition(newPosition, commify(end - start + 1));
return newPosition;
}
+function getPosition()
+{
+// Return current value of position box
+ var tags = document.getElementsByName("position");
+ // There are multiple tags with name == "position" (the visible position text input
+ // and a hidden with id='positionHidden'); we return value of visible element.
+ for (var i = 0; i < tags.length; i++) {
+ var ele = tags[i];
+ if(ele.id != "positionHidden") {
+ return ele.value;
+ }
+ }
+ return null;
+}
+
function setPosition(position, size)
{
// Set value of position and size (in hiddens and input elements).
// We assume size has already been commified.
@@ -223,8 +238,11 @@
});
// jQuery load function with stuff to support drag selection in track img
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) {
@@ -719,8 +737,20 @@
}
//warn("Zipped "+count+" buttons "+countN+" are independent.");
}
+function initImgTblButtons()
+{
+// Make side buttons visible (must also be called when updating rows in the imgTbl).
+ var btns = $("p.btn");
+ if(btns.length > 0) {
+ imgTblZipButtons($('#imgTbl'));
+ $(btns).mouseover( imgTblButtonMouseOver );
+ $(btns).mouseout( imgTblButtonMouseOut );
+ $(btns).show();
+ }
+}
+
function imgTblButtonMouseOver()
{
// Highlights a composite set of buttons, regarless of whether tracks are adjacent
var classList = $( this ).attr("class").split(" ");
@@ -947,10 +977,40 @@
{
blockUseMap=true;
}
+// wait for jStore to prepare the storage engine (this token reload code is currently dead code).
+jQuery.jStore && jQuery.jStore.ready(function(engine) {
+ // alert(engine.jri);
+ // wait for the storage engine to be ready.
+ engine.ready(function(){
+ var engine = this;
+ var newToken = document.getElementById("hgt.token").value;
+ if(newToken) {
+ var oldToken = engine.get("token");
+ if(oldToken && oldToken == newToken) {
+ // user has hit the back button.
+ jQuery('body').css('cursor', 'wait');
+ window.location = "../cgi-bin/hgTracks?hgsid=" + getHgsid();
+ }
+ }
+ engine.set("token", newToken);
+ });
+});
+
$(document).ready(function()
{
+ if(jQuery.jStore) {
+ if(0) {
+ 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
if($("FORM").length > 0) {
$('a,area').not("[href*='#']").not("[target]").click(function(i) {
if(blockUseMap==true) {
@@ -981,15 +1041,9 @@
});
}
if($('#imgTbl').length == 1) {
imageV2 = true;
- var btns = $("p.btn");
- if(btns.length > 0) {
- imgTblZipButtons($('#imgTbl'));
- $(btns).mouseover( imgTblButtonMouseOver );
- $(btns).mouseout( imgTblButtonMouseOut );
- $(btns).show();
- }
+ initImgTblButtons();
// Make imgTbl allow draw reorder of imgTrack rows
var imgTable = $(".tableWithDragAndDrop");
if($(imgTable).length > 0) {
$(imgTable).tableDnD({
@@ -1045,9 +1099,9 @@
}
function findMapItem(e)
{
-// Find mapItem for given event
+// Find mapItem for given event; returns item object or null if none found.
var x,y;
if(imageV2) {
// It IS appropriate to use coordinates relative to the img WHEN we have a hit in the right-hand side, but NOT
// when we have a hit in the left hand elements (which do not have relative coordinates).
@@ -1070,9 +1124,27 @@
} else {
x = e.pageX - e.target.offsetLeft;
y = e.pageY - e.target.offsetTop;
}
+ if(e.target.tagName.toUpperCase() == "P") {
+ var a = /p_btn_(.*)/.exec(e.target.id);
+ if(a && a[1]) {
+ // XXXX get title from json
+ var id = a[1];
+ var title;
+ var rec = trackDbJson[id];
+ if(rec) {
+ title = rec.shortLabel;
+ } else {
+ title = id;
+ }
+ return {id: id, title: "configure " + title};
+ } else {
+ return null;
+ }
+ }
var retval = -1;
+ // console.log(e.target.tagName + "; " + e.target.id);
for(var i=0;i<mapItems.length;i++)
{
if(mapItems[i].obj && e.target === mapItems[i].obj) {
// e.target is AREA tag under FF and Safari;
@@ -1093,17 +1165,20 @@
}
// showWarning(x + " " + y + " " + retval + " " + e.target.tagName + " " + $(e.target).attr('src'));
// console.log("findMapItem:", e.clientX, e.clientY, x, y, pos.left, pos.top, retval, mapItems.length, e.target.tagName);
// console.log(e.clientX, pos);
- return retval;
+ if(retval >= 0) {
+ return mapItems[retval];
+ } else {
+ return null;
+ }
}
function mapEvent(e)
{
- var i = findMapItem(e);
- if(i >= 0)
- {
- e.target.title = mapItems[i].title;
+ var o = findMapItem(e);
+ if(o) {
+ e.target.title = o.title;
} else {
// XXXX this doesn't work.
// $('#myMenu').html("<ul id='myMenu' class='contextMenu'><li class='edit'><a href='#img'>Get Image</a></li></ul>");
e.target.title = originalImgTitle;
@@ -1117,13 +1192,12 @@
if(rightclick)
{
return false;
} else {
- var i = findMapItem(e);
- if(i >= 0)
- {
+ var o = findMapItem(e);
+ if(o) {
// XXXX Why does href get changed to "about://" on IE?
- window.location = mapItems[i].href;
+ window.location = o.href;
}
return true;
}
}
@@ -1142,9 +1216,9 @@
return;
}
if(cmd == 'selectWholeGene') {
// bring whole gene into view
- var href = mapItems[selectedMapItem].href;
+ var href = selectedMenuItem.href;
var chromStart, chromEnd;
var a = /hgg_chrom=(\w+)&/.exec(href);
// Many links leave out the chrom (b/c it's in the server side cart as "c")
var chrom = document.getElementById("hgt.chromName").value;
@@ -1174,12 +1248,12 @@
showWarning("couldn't parse out genomic coordinates");
} else {
var newPosition = setPositionByCoordinates(chrom, chromStart, chromEnd);
if(browser == "safari" || imageV2) {
- // See comments below on safari.
- // We need to parse out more stuff to support imageV2 via ajax, but it's probably possible.
+ // We need to parse out more stuff to support resetting the position under imageV2 via ajax, but it's probably possible.
+ // See comments below on safari problems.
jQuery('body').css('cursor', 'wait');
- document.TrackHeaderForm.submit();
+ document.TrackForm.submit();
} else {
jQuery('body').css('cursor', '');
$.ajax({
type: "GET",
@@ -1197,9 +1271,9 @@
// data: ?
jQuery('body').css('cursor', 'wait');
$.ajax({
type: "POST",
- url: "../cgi-bin/hgTrackUi?ajax=1&g=" + mapItems[selectedMapItem].id + "&hgsid=" + getHgsid(),
+ url: "../cgi-bin/hgTrackUi?ajax=1&g=" + selectedMenuItem.id + "&hgsid=" + getHgsid(),
dataType: "html",
trueSuccess: handleTrackUi,
success: catchErrorOrDispatch,
cache: true
@@ -1215,31 +1289,37 @@
} else if (cmd == 'viewImg') {
window.open(trackImg.attr('src'));
} else if (cmd == 'openLink') {
// XXXX This is blocked by Safari's popup blocker (without any warning message).
- window.open(mapItems[selectedMapItem].href);
+ window.open(selectedMenuItem.href);
} else {
- var id = mapItems[selectedMapItem].id;
+ // Change visibility settings:
+ //
+ // First change the select on our form:
+
+ var id = selectedMenuItem.id;
var rec = trackDbJson[id];
if(rec && rec.parentTrack) {
// currently we fall back to the parentTrack
id = rec.parentTrack;
}
$("select[name=" + id + "]").each(function(t) {
$(this).val(cmd);
});
+
+ // Now change the track image
if(imageV2 && cmd == 'hide')
{
// Tell remote cart what happened (to keep them in sync with us).
setCartVar(id, cmd);
$('#tr_' + id).remove();
loadImgAreaSelect(false);
} else if (browser == "safari") {
- // Safari has the following bug: if we update the local map dynamically, the changes don't get registered (even
+ // Safari has the following bug: if we update the local 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.
jQuery('body').css('cursor', 'wait');
- document.TrackHeaderForm.submit();
+ document.TrackForm.submit();
} else {
var data = "hgt.trackImgOnly=1&" + id + "=" + cmd + "&hgsid=" + getHgsid();
if(imageV2) {
data += "&hgt.trackNameFilter=" + id;
@@ -1265,15 +1345,17 @@
function() {
var menu = [];
var selectedImg = " <img src='../images/Green_check.png' height='10' width='10' />";
var done = false;
- if(selectedMapItem >= 0)
- {
- var href = mapItems[selectedMapItem].href;
- var isGene = href.match("hgGene");
- var isHgc = href.match("hgc");
+ if(selectedMenuItem) {
+ var href = selectedMenuItem.href;
+ var isHgc, isGene;
+ if(href) {
+ isGene = href.match("hgGene");
+ isHgc = href.match("hgc");
+ }
var rec = trackDbJson[id];
- var id = mapItems[selectedMapItem].id;
+ var id = selectedMenuItem.id;
var rec = trackDbJson[id];
if(rec && rec.parentTrack) {
// currently we fall back to the parentTrack
id = rec.parentTrack;
@@ -1292,21 +1374,11 @@
var o = new Object();
o[str] = {onclick: function (menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, title); return true;}};
menu.push(o);
});
- menu.push($.contextMenu.separator);
- var o = new Object();
- if(isGene || isHgc) {
- var title = mapItems[selectedMapItem].title || "feature";
- o["Zoom to " + title] = {onclick: function(menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, "selectWholeGene"); return true; }};
- o["Open Link in New Window"] = {onclick: function(menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, "openLink"); return true; }};
- } else {
- o[mapItems[selectedMapItem].title] = {onclick: function(menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, "hgTrackUi"); return true; }};
- }
- menu.push(o);
done = true;
} else {
- // XXXX currently dead code
+ // XXXX currently dead code (unless JSON is enabled in hgTracks.c)
if(rec) {
// XXXX check current state from a hidden variable.
var visibilityStrsOrder = new Array("hide", "dense", "full", "pack", "squish");
var visibilityStrs = new Array("hide", "dense", "squish", "pack", "full");
@@ -1324,8 +1396,20 @@
}
done = true;
}
}
+ if(done) {
+ menu.push($.contextMenu.separator);
+ var o = new Object();
+ if(isGene || isHgc) {
+ var title = selectedMenuItem.title || "feature";
+ o["Zoom to " + title] = {onclick: function(menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, "selectWholeGene"); return true; }};
+ o["Open Link in New Window"] = {onclick: function(menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, "openLink"); return true; }};
+ } else {
+ o[selectedMenuItem.title] = {onclick: function(menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, "hgTrackUi"); return true; }};
+ }
+ menu.push(o);
+ }
}
if(!done) {
var str = "drag-and-zoom mode";
var o = new Object();
@@ -1335,8 +1419,9 @@
}
o[str] = { onclick: function(menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, "dragZoomMode"); return true; }};
menu.push(o);
o = new Object();
+ // console.dir(ele);
str = "hilight mode";
if(!autoHideSetting) {
str += selectedImg;
}
@@ -1347,10 +1432,10 @@
return menu;
},
{
beforeShow: function(e) {
- // console.log(mapItems[selectedMapItem]);
- selectedMapItem = findMapItem(e);
+ // console.log(mapItems[selectedMenuItem]);
+ selectedMenuItem = findMapItem(e);
// XXXX? blockUseMap = true;
},
hideCallback: function() {
// this doesn't work
@@ -1443,17 +1528,17 @@
$('#chrom').attr('src', b[1]);
}
}
if(imageV2 && this.cmd && this.cmd != 'selectWholeGene') {
- // Extract <TR id='tr_ID' class='trDraggable'>...</TR> and update appropriate row in imgTbl;
+ // Extract <TR id='tr_ID'>...</TR> and update appropriate row in imgTbl;
// this updates src in img_left_ID, img_center_ID and img_data_ID and map in map_data_ID
- var id = mapItems[selectedMapItem].id;
+ var id = selectedMenuItem.id;
var rec = trackDbJson[id];
if(rec && rec.parentTrack) {
// currently we fall back to the parentTrack
id = rec.parentTrack;
}
- var str = "<TR id='tr_" + id + "' class='trDraggable'>([\\s\\S]+?)</TR>";
+ var str = "<TR id='tr_" + id + "'[^>]*>([\\s\\S]+?)</TR>";
var reg = new RegExp(str);
a = reg.exec(response);
if(a && a[1]) {
// $('#tr_' + id).html();
@@ -1461,14 +1546,16 @@
$('#tr_' + id).html(a[1]);
// XXXX move following to a shared method
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();
} else {
- showWarning("Couldn't parse out new image");
+ showWarning("Couldn't parse out new image for id: " + id);
}
} else {
if(imageV2) {
a= /<TABLE id=\'imgTbl\'[^>]*>([\S\s]+?)<\/TABLE>/.exec(response);