3d3f084876b33513ffa9047d3129c71f628b6ebc
chmalee
Wed Mar 13 16:29:59 2024 -0700
Show hgc details pages in a dialog on hgTracks. Currently under hg.conf
control , refs #33216
diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index b83ebe5..02ecf90 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -704,82 +704,70 @@
return (posting.blockUseMap === false);
},
blockTheMapOnMouseMove: function (ev)
{
if (!posting.blockUseMap && mouse.hasMoved(ev)) {
posting.blockUseMap=true;
}
},
mapClk: function ()
{
var done = false;
// if we clicked on a merged item then show all the items, similar to clicking a
// dense track to turn it to pack
- if (this && this.href && this.href.indexOf("i=mergedItem") !== -1) {
- var id = this.href.slice(this.href.indexOf("&g="));
- id = id.split(/&[^=]+=/)[1];
+ if (!(this && this.href)) {
+ writeToApacheLog(`no href for mapClk, this = `);
+ }
+ let parsedUrl = parseUrl(this.href);
+ let cgi = parsedUrl.cgi;
+ let id = parsedUrl.queryArgs.g;
+ if (parsedUrl.queryArgs.i === "mergedItem") {
updateObj={};
updateObj[id+".doMergeItems"] = 0;
hgTracks.trackDb[id][id+".doMergeItems"] = 0;
cart.setVarsObj(updateObj,null,false);
imageV2.requestImgUpdate(id, id + ".doMergeItems=0");
return false;
}
- if (false && imageV2.inPlaceUpdate) {
- // XXXX experimental and only turned on in larrym's tree.
- // Use in-place update if the map item just modifies the current position (this is nice
- // because it's faster and preserves the users relative position in the track image).
- //
- // First test handles next/prev item.
- var str = "/cgi-bin/hgTracks\\?position=([^:]+):(.+)&hgsid=(\\d+)" +
- "&(hgt.(next|prev)Item=[^&]+)";
- var reg = new RegExp(str);
- var a = reg.exec(this.href);
- if (a && a[1] && a[1] === hgTracks.chromName) {
- imageV2.navigateInPlace("position=" + encodeURIComponent(a[1] + ":" + a[2]) +
- "&" + a[4], null, true);
- done = true;
- } else {
- // handle next/prev exon
- str = "/cgi-bin/hgTracks\\?position=([^:]+):(.+)&hgsid=(\\d+)$";
- reg = new RegExp(str);
- a = reg.exec(this.href);
- if (a && a[1]) {
- imageV2.navigateInPlace("position=" + encodeURIComponent(a[1] + ":" + a[2]),
- null, true);
- done = true;
+ if (done)
+ return false;
+ else {
+ if (cgi === "hgGene") {
+ id = parsedUrl.queryArgs.hgg_type;
+ popUpHgcOrHgGene.hgc(id, this.href);
+ return false;
+ } else if (cgi === "hgTrackUi") {
+ rec = hgTracks.trackDb[id];
+ if (rec && tdbIsLeaf(rec)) {
+ popUp.hgTrackUi(id, false);
} else {
- // handle toggle visibility.
- // Request may include a track set, so we cannot use requestImgUpdate.
- str = "/cgi-bin/hgTracks\\?(position=[^:]+:.+&hgsid=\\d+&([^=]+)=([^&]+))$";
- reg = new RegExp(str);
- a = reg.exec(this.href);
- if (a && a[1]) {
- imageV2.navigateInPlace(a[1], null, true);
- // imageV2.requestImgUpdate(a[1], a[1] + "=" + a[2], "", a[2]);
- done = true;
+ location.assign(href);
}
+ } else if (cgi === "hgc") {
+ if (id.startsWith("multiz")) {
+ // multiz tracks have a form that lets you change highlighted bases
+ // that does not play well in a pop up
+ location.assign(href);
+ return false;
}
+ popUpHgcOrHgGene.hgc(id, this.href);
+ return false;
}
}
- if (done)
- return false;
- else
- return posting.saveSettings(this);
},
saveSettings: function (obj)
{
if (posting.blockUseMap === true) {
return false;
}
if (!obj || !obj.href) // called directly with obj
obj = this; // and from callback without obj
if ($(obj).hasClass('noLink')) // TITLE_BUT_NO_LINK
return false;
if (obj.href.match('#') || obj.target.length > 0) {
//alert("Matched # ["+obj.href+"] or has target:"+obj.target);
@@ -2503,34 +2491,33 @@
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);
+ popUpHgcOrHgGene.hgc(rightClick.selectedMenuItem.id, href);
} else {
- // Remove hgsid to force a new session (see redmine ticket 1333).
+ // XXXX This is blocked by Safari's popup blocker (without any warning message).
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 = [];
@@ -3386,30 +3373,187 @@
} else if (hgTracks.virtModeType == "singleAltHaplo") {
msg += "alt haplotype";
}
msg += " view. "
+ "Select a different viewing mode, or exit and return to normal view.";
}
$('#multiRegionConfigStatusMsg').html(msg);
// Make 'Cancel' button close dialog
$('input[name="Cancel"]').click(function() {
$('#hgTracksDialog').dialog('close');
});
}
};
+var popUpHgcOrHgGene = {
+
+ whichHgcMethod: "", // either hgc or hgGene or whatever else
+ table: "", // the g= parameter
+ title: "",
+ saveAllVars: null, // when a click brings up hgTrackUi or something else with a form
+ loadingId: null, // the id of the loading overlay
+ href: "", // the link we're populating the pop up with
+
+ cleanup: function ()
+ { // Clean out the popup box on close
+ if ($('#hgcDialog').html().length > 0 ) {
+ // clear out html after close to prevent problems caused by duplicate html elements
+ $('#hgcDialog').html("");
+ popUpHgcOrHgGene.whichHgcMethod = "";
+ popUpHgcOrHgGene.title = "";
+ popUpHgcOrHgGene.table = "";
+ if (loadingId) {
+ hideLoadingImage(loadingId);
+ }
+ }
+ },
+
+ _uiDialogRequest: function (table, href)
+ { // popup cfg dialog
+ let cgi = parseUrl(href).pathInfo.split('/')[1];
+ popUpHgcOrHgGene.whichHgcMethod = cgi;
+ // the table name gets passed in
+ popUpHgcOrHgGene.table = table;
+ popUpHgcOrHgGene.title = hgTracks.trackDb[table].shortLabel;
+ popUpHgcOrHgGene.href = href;
+ var rec = hgTracks.trackDb[table];
+ if (popUpHgcOrHgGene.whichHgcMethod === "hgTrackUi" && rec && rec.configureBy) {
+ if (rec.configureBy === 'none')
+ return;
+ else if (rec.configureBy === 'clickThrough') {
+ window.location = cart.addUpdatesToUrl(href);
+ return;
+ } // default falls through to configureBy popup
+ }
+ loadingId = showLoadingImage("imgTbl");
+ $.ajax({
+ type: "GET",
+ url: cart.addUpdatesToUrl(href),
+ dataType: "html",
+ trueSuccess: popUpHgcOrHgGene.uiDialog,
+ success: catchErrorOrDispatch,
+ error: errorHandler,
+ loadingId: loadingId,
+ cache: true
+ });
+ },
+
+ hgc: function (table, url)
+ { // Launches the popup but shields the ajax with a waitOnFunction
+ if (typeof doHgcInPopUp !== 'undefined' && doHgcInPopUp === true) {
+ waitOnFunction(popUpHgcOrHgGene._uiDialogRequest, table, url);
+ } else {
+ window.location = cart.addUpdatesToUrl(url);
+ }
+ },
+
+ uiDialogOk: function (popObj)
+ { // When popup closes with ok
+
+ },
+
+ uiDialog: function (response, status)
+ {
+ // Take html from hgc/hgGene and put it up as a modal dialog.
+
+ // make sure all links (e.g. help links) open up in a new window
+ //response = response.replace(/"+ cleanHtml +"");
+ appendNonceJsToPage(nonceJs);
+
+
+
+ // Strategy for popups with js:
+ // - jsFiles and CSS should not be included in html. Here they are shluped out.
+ // - The resulting files ought to be loadable dynamically (with getScript()),
+ // but this was not working nicely with the modal dialog
+ // Therefore include files must be included with hgc CGI !
+ // - embedded js should not be in the popup box.
+ // - Somethings should be in a popup.ready() function, and this is emulated below,
+ // as soon as the cleanHtml is added
+ // Since there are many possible popup cfg dialogs, the ready should be all inclusive.
+
+ // -- popup.ready() -- Here is the place to do things that might otherwise go
+ // into a $('#pop').ready() routine!
+
+ // Searching for some semblance of size suitability
+ var popMaxHeight = (window.innerHeight - (window.innerHeight * 0.15)); // make 15% of the bottom of the screen still visible
+ var popMaxWidth = (window.innerWidth - (window.innerWidth * 0.1)); // take up 90% of the window
+
+ // Create dialog buttons for UI popup
+ var uiDialogButtons = {};
+ // this could be more buttons later
+ uiDialogButtons.OK = function() {
+ $(this).dialog("close");
+ };
+
+ $('#hgcDialog').dialog({
+ resizable: true, // Let scroll vertically
+ height: popMaxHeight,
+ width: popMaxWidth,
+ minHeight: 200,
+ minWidth: 400,
+ modal: true,
+ closeOnEscape: true,
+ autoOpen: false,
+ buttons: uiDialogButtons,
+
+ open: function (event) {
+ // fix popup to a location -- near the top and somewhat centered on the browser image
+ $(event.target).parent().css('position', 'fixed');
+ $(event.target).parent().css('top', '10%');
+ $('#hgcDialog').find('.filterBy,.filterComp').each(
+ function(i) { // ddcl.js is dropdown checklist lib support
+ if ($(this).hasClass('filterComp'))
+ ddcl.setup(this);
+ else
+ ddcl.setup(this, 'noneIsAll');
+ }
+ );
+ },
+
+ close: function() {
+ popUpHgcOrHgGene.cleanup();
+ }
+ });
+ let titleText = hgTracks.trackDb[popUpHgcOrHgGene.table].shortLabel +
+ " Item Details " +
+ "Open in new window";
+ $('#hgcDialog').dialog('option' , 'title', titleText);
+ $('#hgcDialog').dialog('open');
+
+ // Customize message based on current mode
+ // Make 'Cancel' button close dialog
+ $('input[name="Cancel"]').click(function() {
+ $('#hgcDialog').dialog('close');
+ });
+ }
+};
+
// Show the exported data hubs popup
function showExportedDataHubsPopup() {
let popUp = document.getElementById("exportedDataHubsPopup");
title = popUp.title;
if (title.length === 0 && popUp.getAttribute("originaltitle") !== "") {title = popUp.getAttribute("originaltitle");}
$('#exportedDataHubsPopup').dialog({width:'650', title: title});
}
// Show the recommended track sets popup
function showRecTrackSetsPopup() {
// Update links with current position
$('a.recTrackSetLink').each(function() {
var $this = $(this);
var link = $this.attr("href").replace(/position=.*/, 'position=');
$this.attr("href", link + genomePos.original);