");
$("#myPrompt").dialog({
modal: true,
closeOnEscape: true,
buttons: { "OK": function() {
var myPromptText = $("#myPromptText").val();
$(this).dialog("close");
callback(myPromptText);
}
}
});
},
hit: function (menuItemClicked, menuObject, cmd, args)
{
setTimeout( function() {
rightClick.hitFinish(menuItemClicked, menuObject, cmd, args);
}, 1);
},
hitFinish: function (menuItemClicked, menuObject, cmd, args)
{ // dispatcher for context menu hits
var id = rightClick.selectedMenuItem.id;
var url = null; // TODO: Break this giant routine with shared vars into some sub-functions
var href = null;
var rec = null;
var row = null;
var rows = null;
var selectUpdated = null;
if (menuObject.shown) {
// warn("Spinning: menu is still shown");
setTimeout(function() { rightClick.hitFinish(menuItemClicked, menuObject, cmd); }, 10);
return;
}
if (cmd === 'selectWholeGene' || cmd === 'getDna' || cmd === 'highlightItem') {
// bring whole gene into view or redirect to DNA screen.
href = rightClick.selectedMenuItem.href;
var chrom, chromStart, chromEnd;
// Many links leave out the chrom (b/c it's in the server side cart as "c")
// var chrom = hgTracks.chromName; // This is no longer acceptable
// with multi-window capability drawing multiple positions on multiple chroms.
var a = /hgg_chrom=(\w+)&/.exec(href);
if (a) {
if (a && a[1])
chrom = a[1];
a = /hgg_start=(\d+)/.exec(href);
if (a && a[1])
chromStart = parseInt(a[1]) + 1;
a = /hgg_end=(\d+)/.exec(href);
if (a && a[1])
chromEnd = parseInt(a[1]);
} else {
// a = /hgc.*\W+c=(\w+)/.exec(href);
a = /hgc.*\W+c=(\w+)/.exec(href);
if (a && a[1])
chrom = a[1];
a = /o=(\d+)/.exec(href);
if (a && a[1])
chromStart = parseInt(a[1]) + 1;
a = /t=(\d+)/.exec(href);
if (a && a[1])
chromEnd = parseInt(a[1]);
}
if (!chrom || chrom.length === 0 || !chromStart || !chromEnd) {// 1-based chromStart
warn("couldn't parse out genomic coordinates");
} else {
if (cmd === 'getDna') {
// NOTE: this should be shared with URL generation for getDna blue bar menu
url = "../cgi-bin/hgc?g=getDna&i=mixed&c=" + chrom;
url += "&l=" + (chromStart - 1) + "&r=" + chromEnd;
url += "&db=" + getDb() + "&hgsid=" + getHgsid();
if ( ! window.open(url) ) {
rightClick.windowOpenFailedMsg();
}
} else if (cmd === 'highlightItem') {
if (hgTracks.windows && !hgTracks.virtualSingleChrom) {
// orig way only worked if the entire item was visible in the windows.
//var result = genomePos.chromToVirtChrom(chrom, parseInt(chromStart-1), parseInt(chromEnd));
var result = genomePos.convertChromPosToVirtCoords(chrom, parseInt(chromStart-1), parseInt(chromEnd));
if (result.chromStart != -1)
{
var newPos2 = hgTracks.chromName+":"+(result.chromStart+1)+"-"+result.chromEnd;
dragSelect.highlightThisRegion(newPos2);
}
} else {
var newChrom = hgTracks.chromName;
if (hgTracks.windows && hgTracks.virtualSingleChrom) {
newChrom = hgTracks.windows[0].chromName;
}
var newPos3 = newChrom+":"+(parseInt(chromStart))+"-"+parseInt(chromEnd);
dragSelect.highlightThisRegion(newPos3);
}
} else {
var newPosition = genomePos.setByCoordinates(chrom, chromStart, chromEnd);
var reg = new RegExp("hgg_gene=([^&]+)");
var b = reg.exec(href);
var name;
// pull item name out of the url so we can set hgFind.matches (redmine 3062)
if (b && b[1]) {
name = b[1];
} else {
reg = new RegExp("[&?]i=([^&]+)");
b = reg.exec(href);
if (b && b[1]) {
name = b[1];
}
}
if (imageV2.inPlaceUpdate) {
// XXXX This attempt to "update whole track image in place" didn't work
// for a variety of reasons (e.g. safari doesn't parse map when we
// update on the client side), so this is currently dead code.
// However, this now works in all other browsers, so we may turn this
// on for non-safari browsers (see redmine #4667).
jQuery('body').css('cursor', '');
var data = "hgt.trackImgOnly=1&hgt.ideogramToo=1&position=" +
newPosition + "&hgsid=" + getHgsid();
if (name)
data += "&hgFind.matches=" + name;
$.ajax({
type: "GET",
url: "../cgi-bin/hgTracks",
data: cart.addUpdatesToUrl(data),
dataType: "html",
trueSuccess: imageV2.updateImgAndMap,
success: catchErrorOrDispatch,
error: errorHandler,
cmd: cmd,
loadingId: showLoadingImage("imgTbl"),
cache: false
});
} else {
// do a full page refresh to update hgTracks image
jQuery('body').css('cursor', 'wait');
var ele;
if (document.TrackForm)
ele = document.TrackForm;
else
ele = document.TrackHeaderForm;
if (name)
cart.addVarsToQueue(['hgFind.matches'], [name]);
ele.submit();
}
}
}
} else if (cmd === 'zoomCodon' || cmd === 'zoomExon') {
var num, ajaxCmd, msg;
if (cmd === 'zoomCodon') {
msg = "Please enter the codon number to jump to:";
ajaxCmd = 'codonToPos';
} else {
msg = "Please enter the exon number to jump to:";
ajaxCmd = 'exonToPos';
}
rightClick.myPrompt(msg, function(results) {
$.ajax({
type: "GET",
url: "../cgi-bin/hgApi",
data: cart.varsToUrlData({ 'db': getDb(), 'cmd': ajaxCmd, 'num': results,
'table': args.table, 'name': args.name }),
trueSuccess: rightClick.handleZoomCodon,
success: catchErrorOrDispatch,
error: errorHandler,
cache: true
});
});
} else if (cmd === 'hgTrackUi_popup') {
// Launches the popup but shields the ajax with a waitOnFunction
popUp.hgTrackUi( rightClick.selectedMenuItem.id, false );
} else if (cmd === 'hgTrackUi_follow') {
url = "hgTrackUi?hgsid=" + getHgsid() + "&g=";
rec = hgTracks.trackDb[id];
if (tdbHasParent(rec) && tdbIsLeaf(rec))
url += rec.parentTrack;
else {
// The button already has the ref
var link = normed($( 'td#td_btn_'+ rightClick.selectedMenuItem.id ).children('a'));
if (link)
url = $(link).attr('href');
else
url += rightClick.selectedMenuItem.id;
}
location.assign(url);
} else if (cmd === 'viewImg') {
// Fetch a new copy of track img and show it to the user in another window. This code
// assume we have updated remote cart with all relevant chages (e.g. drag-reorder).
jQuery('body').css('cursor', 'wait');
$.ajax({
type: "GET",
url: "../cgi-bin/hgTracks",
data: cart.varsToUrlData({ 'hgt.imageV1': '1','hgt.trackImgOnly': '1',
'hgsid': getHgsid() }),
dataType: "html",
trueSuccess: rightClick.handleViewImg,
success: catchErrorOrDispatch,
error: errorHandler,
cmd: cmd,
cache: false
});
} else if (cmd === 'openLink' || cmd === 'followLink') {
href = rightClick.selectedMenuItem.href;
var vars = new Array("c", "l", "r", "db");
var valNames = new Array("chromName", "winStart", "winEnd");
for (var i in vars) {
// make sure the link contains chrom and window width info
// (necessary b/c we are stripping hgsid and/or the cart may be empty);
// but don't add chrom to wikiTrack links (see redmine #2476).
var v = vars[i];
var val;
if (v === "db") {
val = getDb();
} else {
val = hgTracks[valNames[i]];
}
if (val
&& id !== "wikiTrack"
&& (href.indexOf("?" + v + "=") === -1)
&& (href.indexOf("&" + v + "=") === -1)) {
href = href + "&" + v + "=" + val;
}
}
if (cmd === 'followLink') {
// XXXX This is blocked by Safari's popup blocker (without any warning message).
location.assign(href);
} else {
// Remove hgsid to force a new session (see redmine ticket 1333).
href = removeHgsid(href);
if ( ! window.open(href) ) {
rightClick.windowOpenFailedMsg();
}
}
} else if (cmd === 'float') {
if (rightClick.floatingMenuItem && rightClick.floatingMenuItem === id) {
$.floatMgr.FOArray = [];
rightClick.floatingMenuItem = null;
} else {
if (rightClick.floatingMenuItem) {
// This doesn't work.
$('#img_data_' + rightClick.floatingMenuItem).parent().restartFloat();
// This does work
$.floatMgr.FOArray = [];
}
rightClick.floatingMenuItem = id;
rightClick.reloadFloatingItem();
imageV2.requestImgUpdate(id, "hgt.transparentImage=0", "");
}
} else if (cmd === 'hideSet') {
row = $( 'tr#tr_' + id );
rows = dragReorder.getContiguousRowSet(row);
if (rows && rows.length > 0) {
var varsToUpdate = {};
// from bottom up, just in case remove screws with us
for (var ix=rows.length - 1; ix >= 0; ix--) {
var rowId = $(rows[ix]).attr('id').substring('tr_'.length);
// Remove subtrack level vis and explicitly uncheck.
varsToUpdate[rowId] = '[]';
varsToUpdate[rowId+'_sel'] = 0;
$(rows[ix]).remove();
}
if (objNotEmpty(varsToUpdate)) {
cart.setVarsObj(varsToUpdate);
}
imageV2.afterImgChange(true);
}
} else if (cmd === 'hideComposite') {
rec = hgTracks.trackDb[id];
if (tdbIsSubtrack(rec)) {
row = $( 'tr#tr_' + id );
rows = dragReorder.getCompositeSet(row);
// from bottom up, just in case remove screws with us
if (rows && rows.length > 0) {
for (var rIx=rows.length - 1; rIx >= 0; rIx--) {
$(rows[rIx]).remove();
}
selectUpdated = vis.update(rec.parentTrack, 'hide');
cart.setVars( [rec.parentTrack], ['hide']);
imageV2.afterImgChange(true);
}
}
} else if (cmd === 'jumpToHighlight') { // If highlight exists for this assembly, jump to it
if (hgTracks.highlight) {
var newPos = parsePositionWithDb(hgTracks.highlight);
if (newPos && newPos.db === getDb()) {
if ( $('#highlightItem').length === 0) { // not visible? jump to it
var curPos = parsePosition(genomePos.get());
var diff = ((curPos.end - curPos.start) - (newPos.end - newPos.start));
if (diff > 0) { // new position is smaller then current, then center it
newPos.start = Math.max( Math.floor(newPos.start - (diff/2) ), 0 );
newPos.end = newPos.start + (curPos.end - curPos.start);
}
}
if (imageV2.inPlaceUpdate) {
var params = "position=" + newPos.chrom+':'+newPos.start+'-'+newPos.end;
imageV2.navigateInPlace(params, null, true);
} else {
genomePos.setByCoordinates(newPos.chrom, newPos.start, newPos.end);
jQuery('body').css('cursor', 'wait');
document.TrackHeaderForm.submit();
}
}
}
} else if (cmd === 'removeHighlight') {
hgTracks.highlight = null;
cart.setVarsObj({ 'highlight': '[]' });
imageV2.highlightRegion();
} else { // if ( cmd in 'hide','dense','squish','pack','full','show' )
// Change visibility settings:
//
// First change the select on our form:
rec = hgTracks.trackDb[id];
selectUpdated = vis.update(id, cmd);
// Now change the track image
if (imageV2.enabled && cmd === 'hide') {
// Hide local display of this track and update server side cart.
// Subtracks controlled by 2 settings so del vis and set sel=0.
if (tdbIsSubtrack(rec)) {
// Remove subtrack level vis and explicitly uncheck.
cart.setVars( [ id, id+"_sel" ], [ '[]', 0 ] );
} else if (tdbIsFolderContent(rec)) {
// supertrack children need to have _sel set to trigger superttrack reshaping
cart.setVars( [ id, id+"_sel" ], [ 'hide', 0 ] );
} else {
cart.setVars([id], ['hide']); // Others, just set vis hide.
}
$(document.getElementById('tr_' + id)).remove();
imageV2.afterImgChange(true);
} else if (!imageV2.mapIsUpdateable) {
jQuery('body').css('cursor', 'wait');
if (selectUpdated) {
// assert(document.TrackForm);
document.TrackForm.submit();
} else {
// Add vis update to queue then submit
cart.addVarsToQueue([id], [cmd]);
document.TrackHeaderForm.submit();
}
} else {
imageV2.requestImgUpdate(id, id + "=" + cmd, "", cmd);
}
}
},
makeHitCallback: function (title)
{ // stub to avoid problem with a function closure w/n a loop
return function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked, menuObject, title); return true;
};
},
reloadFloatingItem: function ()
{ // currently dead (experimental code)
if (rightClick.floatingMenuItem) {
$('#img_data_' + rightClick.floatingMenuItem).parent().makeFloat(
{x:"current",y:"current", speed: 'fast', alwaysVisible: true, alwaysTop: true});
}
},
makeImgTag: function (img)
{ // Return img tag with explicit dimensions for img (dimensions are currently hardwired).
// This fixes the "weird shadow problem when first loading the right-click menu"
// seen in FireFox 3.X, which occurred b/c FF doesn't actually fetch the image until
// the menu is being shown.
return "

";
},
load: function (img)
{
rightClick.menu = img.contextMenu(function() {
popUp.cleanup(); // Popup box is not getting closed properly so must do it here
if ( ! rightClick.selectedMenuItem ) // This is literally an edge case so ignore
return;
var o; // TODO: Break this giant routine with shared vars into some sub-functions
var str;
var rec = null;
var menu = [];
var selectedImg = rightClick.makeImgTag("greenChecksm.png");
var blankImg = rightClick.makeImgTag("invisible16.png");
var done = false;
if (rightClick.selectedMenuItem && rightClick.selectedMenuItem.id) {
var href = rightClick.selectedMenuItem.href;
var isHgc, isGene;
if (href) {
isGene = href.match("hgGene");
isHgc = href.match("hgc");
}
var id = rightClick.selectedMenuItem.id;
rec = hgTracks.trackDb[id];
var offerHideSubset = false;
var offerHideComposite = false;
var offerSingles = true;
var row = $( 'tr#tr_' + id );
if (row) {
var btn = $(row).find('p.btnBlue'); // btnBlue means cursor over left button
if (btn.length === 1) {
var compositeSet = dragReorder.getCompositeSet(row);
if (compositeSet && compositeSet.length > 0) { // There is composite set
offerHideComposite = true;
$( compositeSet ).find('p.btn').addClass('blueButtons');// blue persists
var subSet = dragReorder.getContiguousRowSet(row);
if (subSet && subSet.length > 1) {
offerSingles = false;
if (subSet.length < compositeSet.length) {
offerHideSubset = true;
$( subSet ).addClass("greenRows"); // green persists
}
}
}
}
}
// First option is hide sets
if (offerHideComposite) {
if (offerHideSubset) {
o = {};
o[blankImg + " hide track subset (green)"] = {
onclick: rightClick.makeHitCallback('hideSet')};
menu.push(o);
}
o = {};
str = blankImg + " hide track set";
if (offerHideSubset)
str += " (blue)";
o[str] = {onclick: rightClick.makeHitCallback('hideComposite')};
menu.push(o);
}
// Second set of options: visibility for single track
if (offerSingles) {
if (offerHideComposite)
menu.push($.contextMenu.separator);
// XXXX what if select is not available (b/c trackControlsOnMain is off)?
// Move functionality to a hidden variable?
var select = $("select[name=" + escapeJQuerySelectorChars(id) + "]");
if (select.length > 1)
// Not really needed if $('#hgTrackUiDialog').html(""); has worked
select = [ $(select)[0] ];
var cur = $(select).val();
if (cur) {
$(select).children().each(function(index, o) {
var title = $(this).val();
str = blankImg + " " + title;
if (title === cur)
str = selectedImg + " " + title;
o = {};
o[str] = {onclick: function (menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked, menuObject, title);
return true;}};
menu.push(o);
});
done = true;
} else {
if (rec) {
// XXXX check current state from a hidden variable.
var visStrings = new Array("hide","dense","squish","pack","full");
for (var i in visStrings) {
// use maxVisibility and change hgTracks so it can hide subtracks
o = {};
str = blankImg + " " + visStrings[i];
if (rec.canPack
|| (visStrings[i] !== "pack" && visStrings[i] !== "squish")) {
if (rec.localVisibility) {
if (visStrings[i] === rec.localVisibility) {
str = selectedImg + " " + visStrings[i];
}
} else if (visStrings[i] === vis.enumOrder[rec.visibility]) {
str = selectedImg + " " + visStrings[i];
}
o[str] = { onclick:
rightClick.makeHitCallback(visStrings[i])
};
menu.push(o);
}
}
done = true;
}
}
}
if (done) {
o = {};
var any = false;
var title = rightClick.selectedMenuItem.title || "feature";
var maxLength = 60;
if (title.length > maxLength) {
title = title.substring(0, maxLength) + "...";
}
if (isGene || isHgc || id === "wikiTrack") {
// Add "Open details..." item
var displayItemFunctions = false;
if (rec) {
if (rec.type.indexOf("wig") === 0
|| rec.type.indexOf("bigWig") === 0
|| id === "wikiTrack") {
displayItemFunctions = false;
} else if (rec.type.indexOf("expRatio") === 0) {
displayItemFunctions = title !== "zoomInMore";
} else {
displayItemFunctions = true;
}
}
if (isHgc && href.indexOf('g=gtexGene') !== -1) {
// For GTEx gene mouseovers, replace title (which may be a tissue name) with
// item (gene) name
a = /i=([^&]+)/.exec(href);
if (a && a[1]) {
title = a[1];
}
}
if (displayItemFunctions) {
o[rightClick.makeImgTag("magnify.png") + " Zoom to " + title] = {
onclick: function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked, menuObject,
"selectWholeGene"); return true;
}
};
o[rightClick.makeImgTag("highlight.png") + " Highlight " + title] =
{ onclick: function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked, menuObject,
"highlightItem");
return true;
}
};
if (rightClick.supportZoomCodon && rec.type.indexOf("genePred") !== -1) {
// http://hgwdev-larrym.cse.ucsc.edu/cgi-bin/hgGene?hgg_gene=uc003tqk.2&hgg_prot=P00533&hgg_chrom=chr7&hgg_start=55086724&hgg_end=55275030&hgg_type=knownGene&db=hg19&c=chr7
var name, table;
var reg = new RegExp("hgg_gene=([^&]+)");
var a = reg.exec(href);
if (a && a[1]) {
name = a[1];
reg = new RegExp("hgg_type=([^&]+)");
a = reg.exec(href);
if (a && a[1]) {
table = a[1];
}
} else {
// http://hgwdev-larrym.cse.ucsc.edu/cgi-bin/hgc?o=55086724&t=55275031&g=refGene&i=NM_005228&c=chr7
// http://hgwdev-larrym.cse.ucsc.edu/cgi-bin/hgc?o=55086713&t=55270769&g=wgEncodeGencodeManualV4&i=ENST00000455089&c=chr7
reg = new RegExp("i=([^&]+)");
a = reg.exec(href);
if (a && a[1]) {
name = a[1];
reg = new RegExp("g=([^&]+)");
a = reg.exec(href);
if (a && a[1]) {
table = a[1];
}
}
}
if (name && table) {
o[rightClick.makeImgTag("magnify.png")+" Zoom to codon"] =
{ onclick: function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked, menuObject,
"zoomCodon",
{name: name, table: table});
return true;}
};
o[rightClick.makeImgTag("magnify.png")+" Zoom to exon"] = {
onclick: function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked, menuObject,
"zoomExon",
{name: name, table: table});
return true; }
};
}
}
o[rightClick.makeImgTag("dnaIcon.png")+" Get DNA for "+title] = {
onclick: function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked, menuObject, "getDna");
return true; }
};
}
o[rightClick.makeImgTag("bookOut.png")+
" Open details page in new window..."] = {
onclick: function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked, menuObject, "openLink");
return true; }
};
any = true;
}
if (href && href.length > 0) {
// Add "Show details..." item
if (title.indexOf("Click to alter ") === 0) {
// suppress the "Click to alter..." items
} else if (rightClick.selectedMenuItem.href.indexOf("cgi-bin/hgTracks")
!== -1) {
// suppress menu items for hgTracks links (e.g. Next/Prev map items).
} else {
var item;
if (title === "zoomInMore")
// avoid showing menu item that says
// "Show details for zoomInMore..." (redmine 2447)
item = rightClick.makeImgTag("book.png") + " Show details...";
else
item = rightClick.makeImgTag("book.png")+" Show details for "+
title + "...";
o[item] = {onclick: function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked,menuObject,"followLink");
return true; }
};
any = true;
}
}
if (any) {
menu.push($.contextMenu.separator);
menu.push(o);
}
}
}
if (rightClick.selectedMenuItem && rec) {
// Add cfg options at just shy of end...
o = {};
if (tdbIsLeaf(rec)) {
if (rec.configureBy !== 'none'
&& (!tdbIsCompositeSubtrack(rec) || rec.configureBy !== 'clickThrough')) {
// Note that subtracks never do clickThrough because
// parentTrack cfg is the desired clickThrough
o[rightClick.makeImgTag("wrench.png")+" Configure "+rec.shortLabel] = {
onclick: function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked, menuObject, "hgTrackUi_popup");
return true; }
};
}
if (rec.parentTrack) {
o[rightClick.makeImgTag("folderWrench.png")+" Configure "+
rec.parentLabel + " track set..."] = {
onclick: function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked,menuObject,"hgTrackUi_follow");
return true; }
};
}
} else {
o[rightClick.makeImgTag("folderWrench.png")+" Configure "+rec.shortLabel +
" track set..."] = {
onclick: function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked, menuObject, "hgTrackUi_follow");
return true; }
};
}
if (jQuery.floatMgr) {
o[(rightClick.selectedMenuItem.id === rightClick.floatingMenuItem ?
selectedImg : blankImg) + " float"] = {
onclick: function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked, menuObject, "float");
return true; }
};
}
menu.push($.contextMenu.separator);
menu.push(o);
}
menu.push($.contextMenu.separator);
if (hgTracks.highlight) {
if (hgTracks.highlight.search(getDb() + '.') === 0) {
var currentlySeen = ($('#highlightItem').length > 0);
o = {};
// Jumps to highlight when not currently seen in image
var text = (currentlySeen ? " Zoom" : " Jump") + " to highlighted region";
o[rightClick.makeImgTag("highlightZoom.png") + text] = {
onclick: rightClick.makeHitCallback('jumpToHighlight')
};
if ( currentlySeen ) { // Remove only when seen
o[rightClick.makeImgTag("highlightRemove.png") +
" Remove highlighting"] = {
onclick: rightClick.makeHitCallback('removeHighlight')
};
}
menu.push(o);
}
}
// Add view image at end
o = {};
o[rightClick.makeImgTag("eye.png") + " View image"] = {
onclick: function(menuItemClicked, menuObject) {
rightClick.hit(menuItemClicked, menuObject, "viewImg");
return true; }
};
menu.push(o);
return menu;
},
{
beforeShow: function(e) {
// console.log(mapItems[rightClick.selectedMenuItem]);
rightClick.selectedMenuItem = rightClick.findMapItem(e);
// XXXX? posting.blockUseMap = true;
return true;
},
hideTransition:'hide', // hideCallback fails if these are not defined.
hideSpeed:10,
hideCallback: function() {
$('p.btn.blueButtons').removeClass('blueButtons');
$('tr.trDraggable.greenRows').removeClass('greenRows');
}
});
return;
}
};
//////////////////////////////////
//// external tools ////
//////////////////////////////////
function showExtToolDialog() {
/* show the 'send to external tool' dialog */
// information about external tools is stored in the extTools global list
// defined by a ";
- var reg = new RegExp(srcPattern);
- var a = reg.exec(strippedJsFiles.jsFiles[i]);
- if (a && a[1]) {
- if (a[1].match("inline")) {
- inlinePath = a[1];
- //alert("SRC found: "+a[1]); // DEBUG REMOVE
- }
- }
- }
- }
- if (inlinePath !== "") {
- //alert("inlinePath found: "+inlinePath); // DEBUG REMOVE
- var js = genomePos.fetchInlineJs(inlinePath);
- //alert(js); // DEBUG REMOVE
- response += ("");
- newJson = scrapeVariable(response, "hgTracks");
- }
- }
-
//alert(JSON.stringify(newJson)); // DEBUG Example
var oldJson = hgTracks;
var valid = false;
if (!newJson) {
var stripped = {};
stripJsEmbedded(response, true, stripped);
if ( ! stripped.warnMsg )
warn("hgTracks object is missing from the response");
} else {
if (this.id) {
if (newJson.trackDb[this.id]) {
var visibility = vis.enumOrder[newJson.trackDb[this.id].visibility];
var limitedVis;
if (newJson.trackDb[this.id].limitedVis)
limitedVis = vis.enumOrder[newJson.trackDb[this.id].limitedVis];
if (this.newVisibility && limitedVis && this.newVisibility !== limitedVis)
// see redmine 1333#note-9
alert("There are too many items to display the track in " +
this.newVisibility + " mode.");
var rec = oldJson.trackDb[this.id];
rec.limitedVis = newJson.trackDb[this.id].limitedVis;
vis.update(this.id, visibility);
valid = true;
} else {
warn("Invalid hgTracks.trackDb received from the server");
}
} else {
valid = true;
}
}
if (valid) {
if (imageV2.enabled
&& this.id
&& this.cmd
&& this.cmd !== 'wholeImage'
&& this.cmd !== 'selectWholeGene'
&& !newJson.virtChromChanged) {
// Extract
...
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 = this.id;
if (imageV2.updateImgForId(response, id, false)) {
imageV2.afterReload(id);
imageV2.updateBackground(response); // Added by galt to update window separators
} else {
warn("Couldn't parse out new image for id: " + id);
// Very helpful when debugging and alert doesn't render the html:
//alert("Couldn't parse out new image for id: " + id+"BR"+response);
}
} else {
if (imageV2.enabled) {
// Implement in-place updating of hgTracks image
// GALT delaying this until after newJson updated in hgTracks so disguising works
//genomePos.setByCoordinates(newJson.chromName, newJson.winStart + 1, newJson.winEnd);
$("input[name='c']").val(newJson.chromName);
$("input[name='l']").val(newJson.winStart);
$("input[name='r']").val(newJson.winEnd);
if (newJson.cgiVersion !== oldJson.cgiVersion || newJson.virtChromChanged) {
// Must reload whole page because of a new version on the server;
// this should happen very rarely. Note that we have already updated
// position based on the user's action.
imageV2.fullReload();
} else {
// Will rebuild image adding new, removing old and resorting tracks
imageV2.updateImgForAllIds(response,oldJson,newJson);
imageV2.updateChromImg(response);
imageV2.updateBackground(response); // Added by galt to update window separators
hgTracks = newJson;
genomePos.original = undefined;
genomePos.setByCoordinates(hgTracks.chromName, hgTracks.winStart + 1, hgTracks.winEnd); // MOVED HERE GALT
initVars();
imageV2.afterReload();
}
} else {
warn("ASSERT: Attempt to update track without advanced javascript features.");
}
}
if (hgTracks.measureTiming) {
imageV2.updateTiming(response);
}
}
if (this.disabledEle) {
this.disabledEle.removeAttr('disabled');
}
if (this.loadingId) {
hideLoadingImage(this.loadingId);
}
jQuery('body').css('cursor', '');
if (valid && this.currentId) {
var top = $(document.getElementById("tr_" + this.currentId)).position().top;
$(window).scrollTop(top - this.currentIdYOffset);
}
},
loadRemoteTracks: function ()
{
if (hgTracks.trackDb) {
for (var id in hgTracks.trackDb) {
var rec = hgTracks.trackDb[id];
if (rec.type === "remote") {
if ($("#img_data_" + id).length > 0) {
// load the remote track renderer via jsonp
rec.loadingId = showLoadingImage("tr_" + id);
var script = document.createElement('script');
var pos = parsePosition(genomePos.get());
var name = rec.remoteTrack || id;
script.setAttribute('src',
rec.url + "?track=" + name +
"&jsonp=imageV2.remoteTrackCallback&position=" +
encodeURIComponent(pos.chrom + ":" + pos.start + "-" + pos.end) +
"&pix=" + $('#imgTbl').width()
);
document.getElementsByTagName('head')[0].appendChild(script);
}
}
}
}
},
remoteTrackCallback: function (rec)
// jsonp callback to load a remote track.
{
if (rec.error) {
alert("retrieval from remote site failed with error: " + rec.error);
} else {
var remoteTrack = rec.track;
for (var track in hgTracks.trackDb) {
if (hgTracks.trackDb[track].remoteTrack === remoteTrack) {
$('#img_data_' + track).attr('style', "left:-116px; top: -23px;");
$('#img_data_' + track).attr('height', rec.height);
// XXXX use width in some way?
// $('#img_data_' + track).attr('width', rec.width);
$('#img_data_' + track).attr('width', $('#img_data_ruler').width());
$('#img_data_' + track).attr('src', rec.img);
/* jshint loopfunc: true */// function inside loop works and replacement is awkward.
$('#td_data_' + track + ' > div').each(function(index) {
if (index === 1) {
var style = $(this).attr('style');
style = style.replace(/height:\s*\d+/i, "height:" + rec.height);
$(this).attr('style', style);
}
});
var style = $('#p_btn_' + track).attr('style');
style = style.replace(/height:\s*\d+/i, "height:" + rec.height);
$('#p_btn_' + track).attr('style', style);
if (hgTracks.trackDb[track].loadingId) {
hideLoadingImage(hgTracks.trackDb[track].loadingId);
}
}
}
}
},
navigateButtonClick: function (ele) // called from hgTracks.c
{ // code to update just the imgTbl in response to navigation buttons (zoom-out etc.).
if (imageV2.inPlaceUpdate) {
var params = ele.name + "=" + ele.value;
$(ele).attr('disabled', 'disabled');
// dinking navigation needs additional data
if (ele.name === "hgt.dinkLL" || ele.name === "hgt.dinkLR") {
params += "&dinkL=" + $("input[name='dinkL']").val();
} else if (ele.name === "hgt.dinkRL" || ele.name === "hgt.dinkRR") {
params += "&dinkR=" + $("input[name='dinkR']").val();
}
imageV2.navigateInPlace(params, $(ele), false);
return false;
} else {
return true;
}
},
updateButtonClick: function (ele) // UNUSED?
{ // code to update the imgTbl based on changes in the track controls.
// This is currently experimental code and is dead in the main branch.
if (imageV2.mapIsUpdateable) {
var data = "";
$("select").each(function(index, o) {
var cmd = $(this).val();
if (cmd === "hide") {
if (hgTracks.trackDb[this.name]) {
alert("Need to implement hide");
}
} else {
if ( ! hgTracks.trackDb[this.name]
|| cmd !== vis.enumOrder[hgTracks.trackDb[this.name].visibility]) {
if (data.length > 0) {
data = data + "&";
}
data = data + this.name + "=" + cmd;
}
}
});
if (data.length > 0) {
imageV2.navigateInPlace(data, null, false);
}
return false;
} else {
return true;
}
},
navigateInPlace: function (params, disabledEle, keepCurrentTrackVisible)
{ // request an hgTracks image, using params
// disabledEle is optional; this element will be enabled when update is complete
// If keepCurrentTrackVisible is true, we try to maintain relative position of the item
// under the mouse after the in-place update.
// Tim thinks we should consider disabling all UI input while we are doing in-place update.
// TODO: waitOnFuction?
// No ajax image update if there are too many tracks!
if (imageV2.manyTracks()) {
imageV2.fullReload(params);
return false; // Shouldn't return from fullReload but I have seen it in FF
}
// If UCSC Genes (or any suggestion) is supposed to be made visible, then do so
if ($("#suggestTrack").length && $('#hgFindMatches').length)
vis.makeTrackVisible($("#suggestTrack").val());
jQuery('body').css('cursor', 'wait');
var currentId, currentIdYOffset;
if (keepCurrentTrackVisible) {
var item = rightClick.currentMapItem || imageV2.lastTrack;
if (item) {
var top = $(document.getElementById("tr_" + item.id)).position().top;
if (top >= $(window).scrollTop()
|| top < $(window).scrollTop() + $(window).height()) {
// don't bother if the item is not currently visible.
currentId = item.id;
currentIdYOffset = top - $(window).scrollTop();
}
}
}
$.ajax({
type: "GET",
url: "../cgi-bin/hgTracks",
data: cart.addUpdatesToUrl(params +
"&hgt.trackImgOnly=1&hgt.ideogramToo=1&hgsid=" + getHgsid()),
dataType: "html",
trueSuccess: imageV2.updateImgAndMap,
success: catchErrorOrDispatch,
error: errorHandler,
cmd: 'wholeImage',
loadingId: showLoadingImage("imgTbl"),
disabledEle: disabledEle,
currentId: currentId,
currentIdYOffset: currentIdYOffset,
cache: false
});
},
disguiseHighlight: function(position)
// disguise highlight position
{
pos = parsePositionWithDb(position);
// DISGUISE
if (hgTracks.virtualSingleChrom && (pos.chrom.search("virt") === 0)) {
var positionStr = pos.chrom+":"+pos.start+"-"+pos.end;
var newPosition = genomePos.disguisePosition(positionStr);
var newPos = parsePosition(newPosition);
pos.chrom = newPos.chrom;
pos.start = newPos.start;
pos.end = newPos.end;
}
return pos.db+"."+pos.chrom+":"+pos.start+"-"+pos.end+pos.color;
},
undisguiseHighlight: function(pos)
// undisguise highlight pos
{
// UN-DISGUISE
if (hgTracks.virtualSingleChrom && (pos.chrom.search("virt") !== 0)) {
var position = pos.chrom+":"+pos.start+"-"+pos.end;
var newPosition = genomePos.undisguisePosition(position);
var newPos = parsePosition(newPosition);
if (newPos) {
pos.chrom = newPos.chrom;
pos.start = newPos.start;
pos.end = newPos.end;
}
}
},
highlightRegion: function()
// highlight vertical region in imgTbl based on hgTracks.highlight (#709).
{
var pos;
var hexColor = '#FFAAAA';
$('.highlightItem').remove();
if (hgTracks.highlight) {
var hlArray = hgTracks.highlight.split("|"); // support multiple highlight items
for (var i = 0; i < hlArray.length; i++) {
hlString = hlArray[i];
pos = parsePositionWithDb(hlString);
// UN-DISGUISE
imageV2.undisguiseHighlight(pos);
if (pos) {
pos.start--; // make start 0-based to match hgTracks.winStart
if (pos.color)
hexColor = pos.color;
}
if (pos && pos.chrom === hgTracks.chromName && pos.db === getDb()
&& pos.start <= hgTracks.imgBoxPortalEnd && pos.end >= hgTracks.imgBoxPortalStart) {
var portalWidthBases = hgTracks.imgBoxPortalEnd - hgTracks.imgBoxPortalStart;
var portal = $('#imgTbl td.tdData')[0];
var leftPixels = $(portal).offset().left + 3; // 3 for borders and cgi item calcs ??
var pixelsPerBase = ($(portal).width() - 2) / portalWidthBases;
var clippedStartBases = Math.max(pos.start, hgTracks.imgBoxPortalStart);
var clippedEndBases = Math.min(pos.end, hgTracks.imgBoxPortalEnd);
var widthPixels = (clippedEndBases - clippedStartBases) * pixelsPerBase;
if (hgTracks.revCmplDisp)
leftPixels += (hgTracks.imgBoxPortalEnd - clippedEndBases) * pixelsPerBase - 1;
else
leftPixels += (clippedStartBases - hgTracks.imgBoxPortalStart) * pixelsPerBase;
// Impossible to get perfect... Okay to overrun by a pixel on each side
leftPixels = Math.floor(leftPixels);
widthPixels = Math.ceil(widthPixels);
if (widthPixels < 2) {
widthPixels = 3;
leftPixels -= 1;
}
var area = jQuery("
");
$(area).css({ backgroundColor: hexColor, // display: 'none'
left: leftPixels + 'px', top: $('#imgTbl').offset().top + 1 + 'px',
width: widthPixels + 'px',
height: $('#imgTbl').css('height') });
$(area).data({leftPixels: leftPixels, widthPixels: widthPixels});// needed by dragScroll
// Larry originally appended to imgTbl, but discovered that doesn't work on IE 8 and 9.
$('body').append($(area));
// z-index is done in css class, so highlight is beneath transparent data images.
// NOTE: ideally highlight would be below transparent blue-lines, but THAT is a
// background-image so z-index can't get below it! PS/PDF looks better for blue-lines!
}
}
}
},
backSupport: (window.History.enabled !== undefined), // support of our back button via:
history: null, // jquery.history.js and HTML5 history API
setupHistory: function ()
{ // Support for back-button using jquery.history.js.
// Sets up the history and initializes a state.
// Since ajax updates leave the browser cached pages different from the server state,
// simple back-button fails. Using a 'dirty flag' we had forced an update from server,
// whenever the back button was hit, meaning there was no going back from server-state!
// NOW using the history API, the back-button triggers a 'statechange' event which can
// contain data. We save the position in the data and ajax update the image when the
// back-button is pressed. This works great for going back through ajax-updated position
// changes, but is a bit messier when going back past a full-page retrieved state (as
// described below).
// NOTE: many things besides position could be ajax updated (e.g. track visibility). We are
// using the back-button to keep track of position only. Since the image should be updated
// every-time the back button is pressed, all track settings should persist (not go back).
// What will occasionally fail is vis box state and group expansion state. This is because
// the back-button goes to a browser cached page and then the image alone is updated.
imageV2.history = window.History;
// The 'statechange' function triggerd by the back-button.
// Whenever the position changes, then use ajax-update to refetch the position
imageV2.history.Adapter.bind(window,'statechange',function(){
var prevDbPos = imageV2.history.getState().data.lastDbPos;
var prevPos = imageV2.history.getState().data.position;
var curDbPos = hgTracks.lastDbPos;
if (prevDbPos && prevDbPos !== curDbPos) {
// NOTE: this function is NOT called when backing past a full retrieval boundary
genomePos.set(decodeURIComponent(prevPos));
imageV2.navigateInPlace("" + prevDbPos, null, false);
}
});
// With history support it is best that most position changes will ajax-update the image
// This ensures that the 'go' and 'refresh' button will do so unless the chrom changes.
$("input[value='go'],input[value='refresh']").click(function () {
var newPos = genomePos.get().replace(/,/g,'');
if (newPos.length > 2000) {
alert("Sorry, you cannot paste identifiers or sequences with more than 2000 characters into this box.");
$('input[name="hgt.positionInput"]').val("");
return false;
}
var newDbPos = hgTracks.lastDbPos;
if ( ! imageV2.manyTracks() ) {
var newChrom = newPos.split(':')[0];
var oldChrom = genomePos.getOriginalPos().split(':')[0];
if (newChrom === oldChrom) {
imageV2.markAsDirtyPage();
imageV2.navigateInPlace("position=" + newPos, null, false);
window.scrollTo(0,0);
return false;
}
}
// If not just image update AND there are vis updates waiting...
if (cart.updatesWaiting()) {
var url = "../cgi-bin/hgTracks?position=" + newPos + "&" + cart.varsToUrlData({ 'db': getDb(), 'hgsid': getHgsid() });
window.location.assign(url);
return false;
}
// redirect to hgBlat if the input looks like a DNA sequence
// minimum length=19 so we do not accidentally redirect to hgBlat for a gene identifier
// like ATG5
var dnaRe = new RegExp("^(>[^\n\r ]+[\n\r ]+)?(\\s*[actgnACTGN \n\r]{19,}\\s*)$");
if (dnaRe.test(newPos)) {
var blatUrl = "hgBlat?type=BLAT%27s+guess&userSeq="+newPos;
window.location.href = blatUrl;
return false;
}
return true;
});
// Have vis box changes update cart through ajax. This helps keep page/cart in sync.
vis.initForAjax();
// We reach here from these possible paths:
// A) Forward: Full page retrieval: hgTracks is first navigated to (or chrom change)
// B) Back-button past a full retrieval (B in: ->A,->b,->c(full page),->d,<-c,<-B(again))
// B1) Dirty page: at least one non-position change (e.g. 1 track vis changed in b)
// B2) Clean page: only position changes from A->b->|
var curPos = encodeURIComponent(genomePos.get().replace(/,/g,''));
var curDbPos = hgTracks.lastDbPos;
var cachedPos = imageV2.history.getState().data.position;
var cachedDbPos = imageV2.history.getState().data.lastDbPos;
// A) Forward: Full page retrieval: hgTracks is first navigated to (or chrom change)
if (!cachedDbPos) { // Not a back-button operation
// set the current position into history outright (will replace). No img update needed
imageV2.setInHistory(true);
} else { // B) Back-button past a full retrieval
genomePos.set(decodeURIComponent(cachedPos));
// B1) Dirty page: at least one non-position change
if (imageV2.isDirtyPage()) {
imageV2.markAsCleanPage();
// Only forcing a full page refresh if chrom changes
var cachedChrom = decodeURIComponent(cachedPos).split(':')[0];
var curChrom = decodeURIComponent( curPos).split(':')[0];
if (cachedChrom === curChrom) {
imageV2.navigateInPlace("db="+getDb()+"&"+cachedDbPos, null, false);
} else {
imageV2.fullReload();
}
} else {
// B2) Clean page: only position changes from a->b
if (cachedDbPos !== curDbPos) {
imageV2.navigateInPlace("db="+getDb()+"&"+cachedDbPos, null, false);
}
}
// Special because FF is leaving vis drop-downs disabled
vis.restoreFromBackButton();
}
},
setInHistory: function (fullPageLoad)
{ // Keep a position history and allow the back-button to work (sort of)
// replaceState on initial page load, pushState on each advance
// When call triggered by back button, the lastPos===newPos, so no action.
var lastDbPos = imageV2.history.getState().data.lastDbPos;
var newPos = encodeURIComponent(genomePos.get().replace(/,/g,'')); // no commas
var newDbPos = hgTracks.lastDbPos;
// A full page load could be triggered by back-button, but then there will be a lastPos
// if this is the case then don't set the position in history again!
if (fullPageLoad && lastDbPos)
return;
if (!lastDbPos || lastDbPos !== newDbPos) {
// Swap the position into the title
var title = $('TITLE')[0].text;
var ttlWords = title.split(' ');
if (ttlWords.length >= 2) {
for (var i=1; i < ttlWords.length; i++) {
if (ttlWords[i].indexOf(':') >= 0) {
ttlWords[i] = genomePos.get();
}
}
title = ttlWords.join(' ');
} else
title = genomePos.get();
var sid = getHgsid();
if (fullPageLoad) {
// Should only be on initial set-up: first navigation to page
imageV2.history.replaceState({lastDbPos: newDbPos, position: newPos, hgsid: + sid },title,
"hgTracks?db="+getDb()+"&"+newDbPos+"&hgsid="+sid);
} else {
// Should be when advancing (not-back-button)
imageV2.history.pushState({lastDbPos: newDbPos, position: newPos, hgsid: + sid },title,
"hgTracks?db="+getDb()+"&"+newDbPos+"&hgsid="+sid);
}
}
}
};
//////////////////////
//// track search ////
//////////////////////
var trackSearch = {
searchKeydown: function (event)
{
if (event.which === 13) {
// Required to fix problem on IE and Safari where value of hgt_tSearch is "-"
// (i.e. not "Search").
// NOTE: must match TRACK_SEARCH_PAGER in hg/inc/searchTracks.h
$("input[name=hgt_tsPage]").val(0);
$('#trackSearch').submit();
// This doesn't work with IE or Safari.
// $('#searchSubmit').click();
}
},
init: function ()
{
// Track search uses tabs
if ($("#tabs").length > 0) {
// Search page specific code
var val = $('#currentTab').val();
$("#tabs").tabs({
show: function(event, ui) {
$('#currentTab').val(ui.panel.id);
},
select: function(event, ui) { findTracks.switchTabs(ui); }
});
$('#tabs').show();
$("#tabs").tabs('option', 'selected', '#' + val);
if (val === 'simpleTab' && $('div#found').length < 1) {
$('input#simpleSearch').focus();
}
$("#tabs").css('font-family', jQuery('body').css('font-family'));
$("#tabs").css('font-size', jQuery('body').css('font-size'));
$('.submitOnEnter').keydown(trackSearch.searchKeydown);
findTracks.normalize();
findTracks.updateMdbHelp(0);
}
}
};
///////////////
//// READY ////
///////////////
$(document).ready(function()
{
// The page may be reached via browser history (back button)
// If so, then this code should detect if the image has been changed via js/ajax
// and will reload the image if necessary.
// NOTE: this is needed for IE but other browsers can detect the dirty page much earlier
if (!imageV2.backSupport) {
if (imageV2.isDirtyPage()) {
// mark as non dirty to avoid infinite loop in chrome.
imageV2.markAsCleanPage();
jQuery('body').css('cursor', 'wait');
window.location = "../cgi-bin/hgTracks?hgsid=" + getHgsid();
return false;
}
}
initVars();
imageV2.loadSuggestBox();
if ($('#pdfLink').length === 1) {
$('#pdfLink').click(function(i) {
var thisForm = normed($('#TrackForm'));
if (thisForm) {
//alert("posting form:"+$(thisForm).attr('name'));
updateOrMakeNamedVariable($(thisForm),'hgt.psOutput','on');
return postTheForm($(thisForm).attr('name'),this.href);
}
return true;
});
}
if (imageV2.enabled) {
// Make imgTbl allow drag reorder of imgTrack rows
dragReorder.init();
var imgTable = $(".tableWithDragAndDrop");
if ($(imgTable).length > 0) {
$(imgTable).tableDnD({
onDragClass: "trDrag",
dragHandle: "dragHandle",
scrollAmount: 40,
onDragStart: function(ev, table, row) {
mouse.saveOffset(ev);
$(document).bind('mousemove',posting.blockTheMapOnMouseMove);
// Can drag a contiguous set of rows if dragging blue button
table.tableDnDConfig.dragObjects = [ row ]; // defaults to just the one
var btn = $( row ).find('p.btnBlue'); // btnBlue means cursor over left button
if (btn.length === 1) {
table.tableDnDConfig.dragObjects = dragReorder.getContiguousRowSet(row);
var compositeSet = dragReorder.getCompositeSet(row);
if (compositeSet && compositeSet.length > 0)
$( compositeSet ).find('p.btn').addClass('blueButtons');// blue persists
}
},
onDrop: function(table, row, dragStartIndex) {
var compositeSet = dragReorder.getCompositeSet(row);
if (compositeSet && compositeSet.length > 0)
$( compositeSet ).find('p.btn').removeClass('blueButtons');// blue persists
if ($(row).attr('rowIndex') !== dragStartIndex) {
// NOTE Even if dragging a contiguous set of rows,
// still only need to check the one under the cursor.
if (dragReorder.setOrder) {
dragReorder.setOrder(table);
}
dragReorder.zipButtons( table );
}
$(document).unbind('mousemove',posting.blockTheMapOnMouseMove);
// Timeout necessary incase the onDrop over map item. onDrop takes precedence.
setTimeout(posting.allowMapClicks,100);
}
});
}
// Drag scroll init
if (hgTracks.imgBoxPortal) {
// Turn on drag scrolling.
$("div.scroller").panImages();
}
// Retrieve tracks via AJAX that may take too long to draw initialliy (i.e. a remote bigWig)
var retrievables = $('#imgTbl').find("tr.mustRetrieve");
if ($(retrievables).length > 0) {
$(retrievables).each( function (i) {
var trackName = $(this).attr('id').substring(3);
imageV2.requestImgUpdate(trackName,"","");
});
}
imageV2.loadRemoteTracks();
makeItemsByDrag.load();
// Any highlighted region must be shown and warnBox must play nice with it.
imageV2.highlightRegion();
// When warnBox is dismissed, any image highlight needs to be redrawn.
$('#warnOK').click(function (e) { imageV2.highlightRegion();});
// Also extend the function that shows the warn box so that it too redraws the highlight.
showWarnBox = (function (oldShowWarnBox) {
function newShowWarnBox() {
oldShowWarnBox.apply();
imageV2.highlightRegion();
}
return newShowWarnBox;
})(showWarnBox);
}
// Drag select in chromIdeogram
if ($('img#chrom').length === 1) {
if ($('area.cytoBand').length >= 1) {
$('img#chrom').chromDrag();
}
}
// Track search uses tabs
trackSearch.init();
// Drag select initialize
if (imageV2.enabled) { // moved from window.load().
dragSelect.load(true);
if ($('#hgTrackUiDialog'))
$('#hgTrackUiDialog').hide();
// Don't load contextMenu if jquery.contextmenu.js hasn't been loaded
if (jQuery.fn.contextMenu) {
rightClick.load(imageV2.imgTbl);
}
}
// jquery.history.js Back-button support
if (imageV2.enabled && imageV2.backSupport) {
imageV2.setupHistory();
}
});