diff --git a/src/hgTracks.js b/src/hgTracks.js index d459d97..971d3af 100644 --- a/src/hgTracks.js +++ b/src/hgTracks.js @@ -30,15 +30,15 @@ var debug = false; /* IE11 compatibility - IE doesn't have string startsWith and never will */ if (!String.prototype.startsWith) { - String.prototype.startsWith = function (searchString, position) { - position = position || 0; - return this.indexOf(searchString, position) === position; - }; + String.prototype.startsWith = function(searchString, position) { + position = position || 0; + return this.indexOf(searchString, position) === position; + }; } function initVars() { // There are various entry points, so we call initVars in several places to make sure all is well - if (typeof (hgTracks) !== "undefined" && !genomePos.original) { + if (typeof(hgTracks) !== "undefined" && !genomePos.original) { // remember initial position and size so we can restore it if user cancels genomePos.original = genomePos.getOriginalPos(); genomePos.originalSize = $('#size').text().replace(/,/g, ""); // strip out any commas @@ -71,7 +71,7 @@ function initVars() // for version had been failing, likely for some time now. // (As of 9.0.9, possibly earlier, the 3rd part of the version is included in the // user agent string, so must be accounted for in string match) - // Consequences were that page refresh was used instead of img update (e.g. + // Consequences were that page refresh was used instead of img update (e.g. // for drag-zoom). And UI dialog was unable to update (e.g. via Apply button). imageV2.mapIsUpdateable = false; var reg = new RegExp("Version\/([0-9]+.[0-9]+)(.[0-9]+)? Safari"); @@ -87,8 +87,8 @@ function initVars() } } -///////////////////////////////////// -////////// Genomic position ///////// + ///////////////////////////////////// + ////////// Genomic position ///////// ///////////////////////////////////// var genomePos = { @@ -116,22 +116,22 @@ var genomePos = { getElement: function () { - // Return position box object + // Return position box object 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; - } + var ele = tags[i]; + if (ele.id !== "positionHidden") { + return ele; + } } return null; }, get: function () { - // Return current value of position box + // Return current value of position box var ele = genomePos.getElement(); if (ele) { return ele.value; @@ -146,11 +146,11 @@ var genomePos = { revertToOriginalPos: function () { - // undo changes to position (i.e. after user aborts a drag-and-select). + // undo changes to position (i.e. after user aborts a drag-and-select). this.set(this.original, this.originalSize); }, - undisguisePosition: function (position) // UN-DISGUISE VMODE + undisguisePosition: function(position) // UN-DISGUISE VMODE { // find the virt position // position should be real chrom span var pos = parsePosition(position); @@ -165,11 +165,11 @@ var genomePos = { var newEnd = -1; var lastW = null; var windows = null; - for (j = 0; j < 3; ++j) { + for (j=0; j < 3; ++j) { if (j === 0) windows = hgTracks.windowsBefore; if (j === 1) windows = hgTracks.windows; if (j === 2) windows = hgTracks.windowsAfter; - for (i = 0, len = windows.length; i < len; ++i) { + for (i=0,len=windows.length; i < len; ++i) { var w = windows[i]; // double check chrom is same thoughout all windows, otherwise warning, return original value if (w.chromName != chromName) { @@ -180,7 +180,7 @@ var genomePos = { return position; // return original } // overlap with position? - // if intersection, + // if intersection, if (w.winEnd > start && end > w.winStart) { var s = Math.max(start, w.winStart); var e = Math.min(end, w.winEnd); @@ -194,11 +194,11 @@ var genomePos = { } } // return new virt undisguised position as a string - var newPos = "multi:" + (newStart + 1) + "-" + newEnd; + var newPos = "multi:" + (newStart+1) + "-" + newEnd; return newPos; }, - disguiseSize: function (position) // DISGUISE VMODE + disguiseSize: function(position) // DISGUISE VMODE { // find the real size of the windows spanned // position should be a real chrom span var pos = parsePosition(position); @@ -208,14 +208,14 @@ var genomePos = { var end = pos.end; var newSize = 0; var windows = null; - for (j = 0; j < 3; ++j) { + for (j=0; j < 3; ++j) { if (j === 0) windows = hgTracks.windowsBefore; if (j === 1) windows = hgTracks.windows; if (j === 2) windows = hgTracks.windowsAfter; - for (i = 0, len = windows.length; i < len; ++i) { + for (i=0,len=windows.length; i < len; ++i) { var w = windows[i]; // overlap with position? - // if intersection, + // if intersection, if (w.winEnd > start && end > w.winStart) { var s = Math.max(start, w.winStart); var e = Math.min(end, w.winEnd); @@ -223,11 +223,11 @@ var genomePos = { } } } - // return real size of the disguised position + // return real size of the disguised position return newSize; }, - disguisePosition: function (position) // DISGUISE VMODE + disguisePosition: function(position) // DISGUISE VMODE { // find the single-chrom range spanned // position should be virt var pos = parsePosition(position); @@ -240,11 +240,11 @@ var genomePos = { var newEnd = -1; var lastW = null; var windows = null; - for (j = 0; j < 3; ++j) { + for (j=0; j < 3; ++j) { if (j === 0) windows = hgTracks.windowsBefore; if (j === 1) windows = hgTracks.windows; if (j === 2) windows = hgTracks.windowsAfter; - for (i = 0, len = windows.length; i < len; ++i) { + for (i=0,len=windows.length; i < len; ++i) { var w = windows[i]; // double check chrom is same thoughout all windows, otherwise warning, return original value if (w.chromName != chromName) { @@ -255,7 +255,7 @@ var genomePos = { return position; // return undisguised original } // overlap with position? - // if intersection, + // if intersection, if (w.virtEnd > start && end > w.virtStart) { var s = Math.max(start, w.virtStart); var e = Math.min(end, w.virtEnd); @@ -269,7 +269,7 @@ var genomePos = { } } // return new non-virt disguised position as a string - var newPos = chromName + ":" + (newStart + 1) + "-" + newEnd; + var newPos = chromName + ":" + (newStart+1) + "-" + newEnd; return newPos; }, @@ -291,7 +291,7 @@ var genomePos = { if (position) { // DISGUISE VMODE //warn("genomePos.set() called, position = "+position); - if (hgTracks.virtualSingleChrom && (position.search("multi:") === 0)) { + if (hgTracks.virtualSingleChrom && (position.search("multi:")===0)) { var newPosition = genomePos.disguisePosition(position); //warn("genomePos.set() position = "+position+", newPosition = "+newPosition); position = newPosition; @@ -311,11 +311,11 @@ var genomePos = { // add commas to positionDisplay var commaPosition = position; if (pos) - commaPosition = pos.chrom + ":" + commify(pos.start) + "-" + commify(pos.end); + commaPosition = pos.chrom+":"+commify(pos.start)+"-"+commify(pos.end); $('#positionDisplay').text(commaPosition); } if (size) { - if (hgTracks.virtualSingleChrom && (position.search("multi:") !== 0)) { + if (hgTracks.virtualSingleChrom && (position.search("multi:")!==0)) { var newSize = genomePos.disguiseSize(position); //warn("genomePos.set() position = "+position+", newSize = "+newSize); if (newSize > 0) @@ -338,7 +338,7 @@ var genomePos = { // https://www.ncbi.nlm.nih.gov/genome/gdv/browser/?id=GCF_000001405.37&chr=4&from=45985744&to=45991655&context=genome genomePos.linkFixup(pos, "ncbiLink", new RegExp("(.+from=)[0-9]+"), "to"); - // Example medaka link: + // Example medaka link: // http://utgenome.org/medakabrowser_ens_jump.php?revision=version1.0&chr=chromosome18&start=14435198&end=14444829 genomePos.linkFixup(pos, "medakaLink", new RegExp("(.+start=)[0-9]+"), "end"); @@ -354,7 +354,7 @@ var genomePos = { $('#wormbaseLink').attr('href', a[1] + pos.start + "-" + pos.end); } } - // Fixup DNA link; e.g.: + // Fixup DNA link; e.g.: // hgc?hgsid=2999470&o=114385768&g=getDna&i=mixed&c=chr7&l=114385768&r=114651696&db=panTro2&hgsid=2999470 if ($('#dnaLink').length) { link = $('#dnaLink').attr('href'); @@ -371,14 +371,14 @@ var genomePos = { imageV2.markAsDirtyPage(); }, - getXLimits: function (img, slop) { + getXLimits : function(img, slop) { // calculate the min/max x position for drag-select, such that user cannot drag into the label area var imgWidth = jQuery(img).width(); var imgOfs = jQuery(img).offset(); - var leftX = hgTracks.revCmplDisp ? imgOfs.left - slop : - imgOfs.left + hgTracks.insideX - slop; + var leftX = hgTracks.revCmplDisp ? imgOfs.left - slop : + imgOfs.left + hgTracks.insideX - slop; var rightX = hgTracks.revCmplDisp ? imgOfs.left + imgWidth - hgTracks.insideX + slop : - imgOfs.left + imgWidth + slop; + imgOfs.left + imgWidth + slop; return [leftX, rightX]; }, @@ -391,8 +391,8 @@ var genomePos = { var slop = 10; // No need to check the x limits anymore, as imgAreaSelect is doing that now. - return ((selection.event.pageY >= (imgOfs.top - slop)) - && (selection.event.pageY < (imgOfs.top + imgHeight + slop))); + return ( (selection.event.pageY >= (imgOfs.top - slop)) + && (selection.event.pageY < (imgOfs.top + imgHeight + slop))); }, pixelsToBases: function (img, selStart, selEnd, winStart, winEnd, addHalfBp) @@ -400,7 +400,7 @@ var genomePos = { var imgWidth = jQuery(img).width() - hgTracks.insideX; var width = hgTracks.winEnd - hgTracks.winStart; var mult = width / imgWidth; // mult is bp/pixel multiplier - + // where does a bp position start on the screen? // For things like drag-select, if the user ends just before the nucleotide itself, do not count // the nucleotide itself as selected. But for things like clicks onto @@ -413,9 +413,9 @@ var genomePos = { var startDelta; // startDelta is how many bp's to the right/left var x1; - // The magic number three appear at another place in the code + // The magic number three appear at another place in the code // as LEFTADD. It was originally annotated as "borders or cgi item calc - // ?" by Larry. It has to be used when going any time when converting + // ?" by Larry. It has to be used when going any time when converting // between pixels and coordinates. selStart -= 3; selEnd -= 3; @@ -442,12 +442,12 @@ var genomePos = { // if user selects space between two bases, start>end can happen if (newStart >= newEnd) - newStart = newEnd - 1; + newStart = newEnd-1; if (newEnd > winEnd) { newEnd = winEnd; } - return {chromStart: newStart, chromEnd: newEnd}; + return {chromStart : newStart, chromEnd : newEnd}; }, chromToVirtChrom: function (chrom, chromStart, chromEnd) @@ -455,7 +455,7 @@ var genomePos = { // Consider the first contiguous set of overlapping regions to define the match (for now). // only works for regions covered by the current hgTracks.windows var virtStart = -1, virtEnd = -1; - var s, e; + var s,e; var i, len; for (i = 0, len = hgTracks.windows.length; i < len; ++i) { var w = hgTracks.windows[i]; @@ -466,7 +466,7 @@ var genomePos = { s = Math.max(chromStart, w.winStart); e = Math.min(chromEnd, w.winEnd); virtStart = w.virtStart + (s - w.winStart); - virtEnd = w.virtStart + (e - w.winStart); + virtEnd = w.virtStart + (e - w.winStart); } else { // until they overlap // do nothing @@ -475,30 +475,30 @@ var genomePos = { if (overlap) { // while they continue to overlap, extend e = Math.min(chromEnd, w.winEnd); - virtEnd = w.virtStart + (e - w.winStart); + virtEnd = w.virtStart + (e - w.winStart); } else { // when they do not overlap anymore, stop break; } } } - return {chromStart: virtStart, chromEnd: virtEnd}; + return {chromStart : virtStart, chromEnd : virtEnd}; }, selectionPixelsToBases: function (img, selection) { // Convert selection x1/x2 coordinates to chromStart/chromEnd. return genomePos.pixelsToBases(img, selection.x1, selection.x2, - hgTracks.winStart, hgTracks.winEnd, true); + hgTracks.winStart, hgTracks.winEnd, true); }, update: function (img, selection, singleClick) { var pos = genomePos.pixelsToBases(img, selection.x1, selection.x2, - hgTracks.winStart, hgTracks.winEnd, true); + hgTracks.winStart, hgTracks.winEnd, true); // singleClick is true when the mouse hasn't moved (or has only moved a small amount). if (singleClick) { - var center = (pos.chromStart + pos.chromEnd) / 2; - pos.chromStart = Math.floor(center - hgTracks.newWinWidth / 2); + var center = (pos.chromStart + pos.chromEnd)/2; + pos.chromStart = Math.floor(center - hgTracks.newWinWidth/2); pos.chromEnd = pos.chromStart + hgTracks.newWinWidth; // clip if (pos.chromStart < hgTracks.chromStart) @@ -512,7 +512,7 @@ var genomePos = { } var newPosition = genomePos.setByCoordinates(hgTracks.chromName, - pos.chromStart + 1, pos.chromEnd); + pos.chromStart+1, pos.chromEnd); return newPosition; }, @@ -525,20 +525,20 @@ var genomePos = { changeAssemblies: function (ele) // UNUSED? Larry's experimental code { // code to update page when user changes assembly select list. $.ajax({ - type: "GET", - url: "../cgi-bin/hgApi", - data: cart.varsToUrlData({'hgsid': getHgsid(), 'cmd': 'defaultPos', 'db': getDb()}), - dataType: "html", - trueSuccess: genomePos.handleChange, - success: catchErrorOrDispatch, - error: errorHandler, - cache: true - }); + type: "GET", + url: "../cgi-bin/hgApi", + data: cart.varsToUrlData({ 'hgsid': getHgsid(), 'cmd': 'defaultPos', 'db': getDb() }), + dataType: "html", + trueSuccess: genomePos.handleChange, + success: catchErrorOrDispatch, + error: errorHandler, + cache: true + }); return false; }, - convertedVirtCoords: {chromStart: -1, chromEnd: -1}, + convertedVirtCoords : {chromStart : -1, chromEnd : -1}, handleConvertChromPosToVirtCoords: function (response, status) { @@ -548,32 +548,32 @@ var genomePos = { warn("convertChromToVirtChrom object is missing from the response"); } else { virtStart = newJson.virtWinStart; - virtEnd = newJson.virtWinEnd; + virtEnd = newJson.virtWinEnd; } - genomePos.convertedVirtCoords = {chromStart: virtStart, chromEnd: virtEnd}; + genomePos.convertedVirtCoords = {chromStart : virtStart, chromEnd : virtEnd}; }, convertChromPosToVirtCoords: function (chrom, chromStart, chromEnd) { // code to convert chrom position to virt coords - genomePos.convertedVirtCoords = {chromStart: -1, chromEnd: -1}; // reset - var pos = chrom + ":" + (chromStart + 1) + "-" + chromEnd; // easier to pass 1 parameter than 3 + genomePos.convertedVirtCoords = {chromStart : -1, chromEnd : -1}; // reset + var pos = chrom+":"+(chromStart+1)+"-"+chromEnd; // easier to pass 1 parameter than 3 $.ajax({ - type: "GET", - async: false, // wait for result - url: "../cgi-bin/hgTracks", - data: cart.varsToUrlData({ 'hgt.convertChromToVirtChrom': pos, 'hgt.trackImgOnly' : 1, 'hgsid': getHgsid(), 'db': getDb() }), - dataType: "html", - trueSuccess: genomePos.handleConvertChromPosToVirtCoords, - success: catchErrorOrDispatch, - error: errorHandler, - cache: false - }); + type: "GET", + async: false, // wait for result + url: "../cgi-bin/hgTracks", + data: cart.varsToUrlData({ 'hgt.convertChromToVirtChrom': pos, 'hgt.trackImgOnly' : 1, 'hgsid': getHgsid(), 'db': getDb() }), + dataType: "html", + trueSuccess: genomePos.handleConvertChromPosToVirtCoords, + success: catchErrorOrDispatch, + error: errorHandler, + cache: false + }); return genomePos.convertedVirtCoords; }, positionDisplayDialog: function () - // Show the virtual and real positions of the windows - { + // Show the virtual and real positions of the windows + { var position = genomePos.get(); position.replace("virt:", "multi:"); var positionDialog = $("#positionDialog")[0]; @@ -585,10 +585,10 @@ var genomePos = { var i, len, end; var matches = /^multi:[0-9]+-([0-9]+)/.exec(position); var modeType = (hgTracks.virtModeType === "customUrl" ? "Custom regions on virtual chromosome" : - (hgTracks.virtModeType === "exonMostly" ? "Exon view of" : - (hgTracks.virtModeType === "geneMostly" ? "Gene view of" : - (hgTracks.virtModeType === "singleAltHaplo" ? "Alternate haplotype as virtual chromosome" : - "Unknown mode")))); + (hgTracks.virtModeType === "exonMostly" ? "Exon view of" : + (hgTracks.virtModeType === "geneMostly" ? "Gene view of" : + (hgTracks.virtModeType === "singleAltHaplo" ? "Alternate haplotype as virtual chromosome" : + "Unknown mode")))); var str = modeType + " " + position; if (matches) { end = matches[1]; @@ -600,18 +600,18 @@ var genomePos = { var w; if (hgTracks.windows.length <= 10) { str += "

\n"; - for (i = 0, len = hgTracks.windows.length; i < len; ++i) { + for (i=0,len=hgTracks.windows.length; i < len; ++i) { w = hgTracks.windows[i]; - str += "\n"; + str += "\n"; } str += "
" + w.chromName + ":" + (w.winStart + 1) + "-" + w.winEnd + "" + - (w.winEnd - w.winStart) + " bp" + "
" + w.chromName + ":" + (w.winStart+1) + "-" + w.winEnd + "" + + (w.winEnd - w.winStart) + " bp" + "

\n"; } else { str += "
\n"; } @@ -621,28 +621,28 @@ var genomePos = { $("#positionDisplayPosition").html(position); } $(positionDialog).dialog({ - modal: true, - title: "Multi-Region Position Ranges", - closeOnEscape: true, - resizable: false, - autoOpen: false, - minWidth: 400, - minHeight: 40, + modal: true, + title: "Multi-Region Position Ranges", + closeOnEscape: true, + resizable: false, + autoOpen: false, + minWidth: 400, + minHeight: 40, - close: function () { - // All exits to dialog should go through this - $(imageV2.imgTbl).imgAreaSelect({hide: true}); - $(this).hide(); - $('body').css('cursor', ''); // Occasionally wait cursor got left behind - } + close: function() { + // All exits to dialog should go through this + $(imageV2.imgTbl).imgAreaSelect({hide:true}); + $(this).hide(); + $('body').css('cursor', ''); // Occasionally wait cursor got left behind + } }); $(positionDialog).dialog('open'); } }; -///////////////////////////////////// -//// Creating items by dragging ///// + ///////////////////////////////////// + //// Creating items by dragging ///// ///////////////////////////////////// var makeItemsByDrag = { @@ -653,21 +653,21 @@ var makeItemsByDrag = { var trackName = imageId.substring('img_data_'.length); var pos = genomePos.selectionPixelsToBases(image, selection); var command = document.getElementById('hgt_doJsCommand'); - command.value = "makeItems " + trackName + " " + hgTracks.chromName; - command.value += " " + pos.chromStart + " " + pos.chromEnd; + command.value = "makeItems " + trackName + " " + hgTracks.chromName; + command.value += " " + pos.chromStart + " " + pos.chromEnd; document.TrackHeaderForm.submit(); return true; }, init: function (trackName) { - // Set up so that they can drag out to define a new item on a makeItems track. - var img = $("#img_data_" + trackName); - if (img && img.length !== 0) { - var imgHeight = imageV2.imgTbl.height(); - jQuery(img.imgAreaSelect( { selectionColor: 'green', outerColor: '', - minHeight: imgHeight, maxHeight: imgHeight, onSelectEnd: makeItemsByDrag.end, - autoHide: true, movable: false})); + // Set up so that they can drag out to define a new item on a makeItems track. + var img = $("#img_data_" + trackName); + if (img && img.length !== 0) { + var imgHeight = imageV2.imgTbl.height(); + jQuery(img.imgAreaSelect( { selectionColor: 'green', outerColor: '', + minHeight: imgHeight, maxHeight: imgHeight, onSelectEnd: makeItemsByDrag.end, + autoHide: true, movable: false})); } }, @@ -682,36 +682,36 @@ var makeItemsByDrag = { } }; -///////////////// -//// posting //// + ///////////////// + //// posting //// ///////////////// var posting = { blockUseMap: false, - blockMapClicks: function () - // Blocks clicking on map items when in effect. Drag opperations frequently call this. - { - posting.blockUseMap = true; + blockMapClicks: function () + // Blocks clicking on map items when in effect. Drag opperations frequently call this. + { + posting.blockUseMap=true; }, - - allowMapClicks: function () - // reallows map clicks. Called after operations that compete with clicks (e.g. dragging) - { + + allowMapClicks:function () + // reallows map clicks. Called after operations that compete with clicks (e.g. dragging) + { $('body').css('cursor', ''); // Explicitly remove wait cursor. - posting.blockUseMap = false; + posting.blockUseMap=false; }, - mapClicksAllowed: function () - // Verify that click-competing operation (e.g. dragging) isn't currently occurring. - { - return (posting.blockUseMap === false); + mapClicksAllowed: function () + // Verify that click-competing operation (e.g. dragging) isn't currently occurring. + { + return (posting.blockUseMap === false); }, blockTheMapOnMouseMove: function (ev) { if (!posting.blockUseMap && mouse.hasMoved(ev)) { - posting.blockUseMap = true; + posting.blockUseMap=true; } }, @@ -733,10 +733,10 @@ var posting = { id = parsedUrl.queryArgs.g.replace("%2D", "-"); } if (parsedUrl.queryArgs.i === "mergedItem") { - updateObj = {}; - updateObj[id + ".doMergeItems"] = 0; - hgTracks.trackDb[id][id + ".doMergeItems"] = 0; - cart.setVarsObj(updateObj, null, false); + updateObj={}; + updateObj[id+".doMergeItems"] = 0; + hgTracks.trackDb[id][id+".doMergeItems"] = 0; + cart.setVarsObj(updateObj,null,false); imageV2.requestImgUpdate(id, id + ".doMergeItems=0"); return false; } @@ -795,7 +795,7 @@ var posting = { thisForm = normed($("FORM").first()); if (thisForm) { //alert("posting form:"+$(thisForm).attr('name')); - return postTheForm($(thisForm).attr('name'), cart.addUpdatesToUrl(obj.href)); + return postTheForm($(thisForm).attr('name'),cart.addUpdatesToUrl(obj.href)); } return true; } @@ -806,17 +806,17 @@ var posting = { /////////////////////// var cart = { // Controls queuing and ultimately updating cart variables vis ajax or submit. Queued vars - // are held in an object with unique keys preventing duplicate updates and ensuring last update + // are held in an object with unique keys preventing duplicate updates and ensuring last update // takes precedence. WARNING: be careful creating an object with variables on the fly: - // cart.setVarsObj({track: vis}) is invalid but cart.setVarsObj({'knownGene': vis}) is ok! + // cart.setVarsObj({track: vis}) is invalid but cart.setVarsObj({'knownGene': vis}) is ok! updateQueue: {}, - + updatesWaiting: function () { // returns TRUE if updates are waiting. return objNotEmpty(cart.updateQueue); }, - + addUpdatesToUrl: function (url) { // adds any outstanding cart updates to the url, then clears the queue if (cart.updatesWaiting()) { @@ -835,12 +835,12 @@ var cart = { } return url; }, - + varsToUrlData: function (varsObj) { // creates a url data (var1=val1&var2=val2...) string from vars object and queue // The queue will be emptied by this call. cart.queueVarsObj(varsObj); // lay ontop of queue, to give new values precedence - + // Now convert to url data and clear queue var urlData = ''; if (cart.updatesWaiting()) { @@ -850,21 +850,21 @@ var cart = { } return urlData; }, - + setVarsObj: function (varsObj, errFunc, async) { // Set all vars in a var hash, appending any queued updates // The default behavior is async = true - //console.log('cart.setVarsObj: were:'+objKeyCount(cart.updateQueue) + + //console.log('cart.setVarsObj: were:'+objKeyCount(cart.updateQueue) + // ' new:'+objKeyCount(varsObj); cart.queueVarsObj(varsObj); // lay ontop of queue, to give new values precedence - + // Now ajax update all in queue and clear queue if (cart.updatesWaiting()) { setVarsFromHash(cart.updateQueue, errFunc, async); cart.updateQueue = {}; } }, - + setVars: function (names, values, errFunc, async) { // ajax updates the cart, and includes any queued updates. cart.updateSessionPanel(); // handles hide from left minibutton @@ -875,7 +875,7 @@ var cart = { { // Add object worth of cart updates to the 'to be updated' queue, so they can be sent to // the server later. Note: hash allows overwriting previous updates to the same variable. if (typeof varsObj !== 'undefined' && objNotEmpty(varsObj)) { - //console.log('cart.queueVarsObj: were:'+objKeyCount(cart.updateQueue) + + //console.log('cart.queueVarsObj: were:'+objKeyCount(cart.updateQueue) + // ' new:'+objKeyCount(varsObj)); for (var name in varsObj) { cart.updateQueue[name] = varsObj[name]; @@ -885,43 +885,43 @@ var cart = { addVarsToQueue: function (names,values) { // creates a string of updates to save for ajax batch or a submit - cart.queueVarsObj(arysToObj(names, values)); + cart.queueVarsObj(arysToObj(names,values)); }, updateSessionPanel: function() { - if (typeof recTrackSetsDetectChanges === 'undefined' || recTrackSetsDetectChanges === null) - return; + if (typeof recTrackSetsDetectChanges === 'undefined' || recTrackSetsDetectChanges === null) + return; - // change color of text - $('span.gbSessionChangeIndicator').addClass('gbSessionChanged'); + // change color of text + $('span.gbSessionChangeIndicator').addClass('gbSessionChanged'); - // change mouseover on the panel. A bit fragile here inserting text in the mouseover specified in - // hgTracks.js, so depends on match with text there, and should present same message as C code - // (Perhaps this could be added as a script tag, so not duplicated) - var txt = $('span.gbSessionLabelPanel').attr('title'); - if (txt && !txt.match(/with changes/)) { - $('span.gbSessionLabelPanel').attr('title', txt.replace( - "track set", - "track set, with changes (added or removed tracks) you have requested")); + // change mouseover on the panel. A bit fragile here inserting text in the mouseover specified in + // hgTracks.js, so depends on match with text there, and should present same message as C code + // (Perhaps this could be added as a script tag, so not duplicated) + var txt = $('span.gbSessionLabelPanel').attr('title'); + if (txt && !txt.match(/with changes/)) { + $('span.gbSessionLabelPanel').attr('title', txt.replace( + "track set", + "track set, with changes (added or removed tracks) you have requested")); } } }; -/////////////////////////////////////////////// -//// visibility (mixed with group toggle) ///// + /////////////////////////////////////////////// + //// visibility (mixed with group toggle) ///// /////////////////////////////////////////////// var vis = { // map cgi enum visibility codes to strings - enumOrder: new Array("hide", "dense", "full", "pack", "squish"), + enumOrder: new Array("hide", "dense", "full", "pack", "squish"), update: function (track, visibility) { // Updates visibility state in hgTracks.trackDb and any visible elements on the page. // returns true if we modify at least one select in the group list var rec = hgTracks.trackDb[track]; var selectUpdated = false; - $("select[name=" + escapeJQuerySelectorChars(track) + "]").each(function (t) { + $("select[name=" + escapeJQuerySelectorChars(track) + "]").each(function(t) { $(this).attr('class', visibility === 'hide' ? 'hiddenText' : 'normalText'); $(this).val(visibility); selectUpdated = true; @@ -961,7 +961,7 @@ var vis = { // of the +/- img tag. imageV2.markAsDirtyPage(); if (arguments.length > 2) - return setTableRowVisibility(button, prefix, "hgtgroup", "group", false, arguments[2]); + return setTableRowVisibility(button, prefix, "hgtgroup", "group",false,arguments[2]); else return setTableRowVisibility(button, prefix, "hgtgroup", "group", true); }, @@ -970,18 +970,18 @@ var vis = { { // Set visibility of all track groups to newState (true means expanded). // This code also modifies the corresponding hidden fields and the gif's of the +/- img tag. imageV2.markAsDirtyPage(); - $(".toggleButton[id$='_button']").each(function (i) { + $(".toggleButton[id$='_button']").each( function (i) { // works for old img type AND new BUTTONS_BY_CSS // - 7: clip '_button' suffix - vis.toggleForGroup(this, this.id.substring(0, this.id.length - 7), newState); + vis.toggleForGroup(this,this.id.substring(0,this.id.length - 7),newState); }); return false; }, - + initForAjax: function() { // To better support the back-button, it is good to eliminate extraneous form puts // Towards that end, we support visBoxes making ajax calls to update cart. var sels = $('select.normalText,select.hiddenText'); - $(sels).on("change", function () { + $(sels).on("change", function() { var track = $(this).attr('name'); if ($(this).val() === 'hide') { var rec = hgTracks.trackDb[track]; @@ -994,7 +994,7 @@ var vis = { $(this).attr('class', 'hiddenText'); } else $(this).attr('class', 'normalText'); - + cart.setVars([track], [$(this).val()]); imageV2.markAsDirtyPage(); return false; @@ -1002,29 +1002,29 @@ var vis = { // Now we can rid the submt of the burden of all those vis boxes var form = $('form#TrackForm'); $(form).on("submit", function () { - $('select.normalText,select.hiddenText').prop('disabled', true); + $('select.normalText,select.hiddenText').prop('disabled',true); }); - $(form).attr('method', 'get'); + $(form).attr('method','get'); }, - restoreFromBackButton: function () - // Re-enabling vis dropdowns is necessary because initForAjax() disables them on submit. + restoreFromBackButton: function() + // Re-enabling vis dropdowns is necessary because initForAjax() disables them on submit. { - $('select.normalText,select.hiddenText').prop('disabled', false); + $('select.normalText,select.hiddenText').prop('disabled',false); } }; -//////////////////////////////////////////////////////////// -// dragSelect is also known as dragZoom or shift-dragZoom // + //////////////////////////////////////////////////////////// + // dragSelect is also known as dragZoom or shift-dragZoom // //////////////////////////////////////////////////////////// var dragSelect = { - hlColor: '#aac6ff', // current highlight color + hlColor : '#aac6ff', // current highlight color hlColorDefault: '#aac6ff', // default highlight color, if nothing specified - areaSelector: null, // formerly "imgAreaSelect". jQuery element used for imgAreaSelect - originalCursor: null, - startTime: null, - escPressed: false, // flag is set when user presses Escape + areaSelector: null, // formerly "imgAreaSelect". jQuery element used for imgAreaSelect + originalCursor: null, + startTime: null, + escPressed : false, // flag is set when user presses Escape selectStart: function (img, selection) { @@ -1051,7 +1051,7 @@ var dragSelect = { return true; }, - findHighlightIdxForPos: function (findPos) { + findHighlightIdxForPos : function(findPos) { // return the index of the highlight string e.g. hg19.chrom1:123-345#AABBDCC that includes a chrom range findPos // mostly copied from drawHighlights() var currDb = getDb(); @@ -1062,12 +1062,12 @@ var dragSelect = { pos = parsePositionWithDb(hlString); imageV2.undisguiseHighlight(pos); - if (!pos) + if (!pos) continue; // ignore invalid position strings pos.start--; if (pos.chrom === hgTracks.chromName && pos.db === currDb - && pos.start <= findPos.chromStart && pos.end >= findPos.chromEnd) { + && pos.start <= findPos.chromStart && pos.end >= findPos.chromEnd) { return i; } } @@ -1075,19 +1075,19 @@ var dragSelect = { return null; }, - saveHlColor: function (hlColor) - // save the current hlColor to the object and also the cart variable hlColor and return it. - // hlColor is a 6-character hex string prefixed by # + saveHlColor : function (hlColor) + // save the current hlColor to the object and also the cart variable hlColor and return it. + // hlColor is a 6-character hex string prefixed by # { - dragSelect.hlColor = hlColor; - cart.setVars(["prevHlColor"], [dragSelect.hlColor], null, false); - hgTracks.prevHlColor = hlColor; // cart.setVars does not update the hgTracks-variables. The cart-variable system is a problem. - return hlColor; + dragSelect.hlColor = hlColor; + cart.setVars(["prevHlColor"], [dragSelect.hlColor], null, false); + hgTracks.prevHlColor = hlColor; // cart.setVars does not update the hgTracks-variables. The cart-variable system is a problem. + return hlColor; }, - loadHlColor: function () - // load hlColor from prevHlColor in the cart, or use default color, set and return it - // color is a 6-char hex string prefixed by # + loadHlColor : function () + // load hlColor from prevHlColor in the cart, or use default color, set and return it + // color is a 6-char hex string prefixed by # { if (hgTracks.prevHlColor) dragSelect.hlColor = hgTracks.prevHlColor; @@ -1096,18 +1096,18 @@ var dragSelect = { return dragSelect.hlColor; }, - highlightThisRegion: function (newPosition, doAdd, hlColor) - // set highlighting newPosition in server-side cart and apply the highlighting in local UI. - // hlColor can be undefined, in which case it defaults to the last used color or the default light blue - // if hlColor is set, it is also saved into the cart. - // if doAdd is true, the highlight is added to the current list. If it is false, all old highlights are deleted. + highlightThisRegion: function(newPosition, doAdd, hlColor) + // set highlighting newPosition in server-side cart and apply the highlighting in local UI. + // hlColor can be undefined, in which case it defaults to the last used color or the default light blue + // if hlColor is set, it is also saved into the cart. + // if doAdd is true, the highlight is added to the current list. If it is false, all old highlights are deleted. { newPosition.replace("virt:", "multi:"); var hlColorName = null; - if (hlColor === "" || hlColor === null || hlColor === undefined) + if (hlColor==="" || hlColor===null || hlColor===undefined) hlColorName = dragSelect.loadHlColor(); else - hlColorName = dragSelect.saveHlColor(hlColor); + hlColorName = dragSelect.saveHlColor( hlColor ); var pos = parsePosition(newPosition); var start = pos.start; @@ -1115,23 +1115,23 @@ var dragSelect = { var newHighlight = makeHighlightString(getDb(), pos.chrom, start, end, hlColorName); newHighlight = imageV2.disguiseHighlight(newHighlight); var oldHighlight = hgTracks.highlight; - if (oldHighlight === undefined || doAdd === undefined || doAdd === false || oldHighlight === "") { + if (oldHighlight===undefined || doAdd===undefined || doAdd===false || oldHighlight==="") { // just set/overwrite the old highlight position, this used to be the default hgTracks.highlight = newHighlight; } else { // add to the end of a |-separated list - hgTracks.highlight = oldHighlight + "|" + newHighlight; + hgTracks.highlight = oldHighlight+"|"+newHighlight; } // we include enableHighlightingDialog because it may have been changed by the dialog - var cartSettings = { 'highlight': hgTracks.highlight, - 'enableHighlightingDialog': hgTracks.enableHighlightingDialog ? 1 : 0 }; + var cartSettings = { 'highlight': hgTracks.highlight, + 'enableHighlightingDialog': hgTracks.enableHighlightingDialog ? 1 : 0 }; if (hgTracks.windows && !hgTracks.virtualSingleChrom) { var nonVirtChrom = ""; - var nonVirtStart = -1; - var nonVirtEnd = -1; - for (i = 0, len = hgTracks.windows.length; i < len; ++i) { + var nonVirtStart = -1; + var nonVirtEnd = -1; + for (i=0,len=hgTracks.windows.length; i < len; ++i) { var w = hgTracks.windows[i]; // overlap with new position? if (w.virtEnd > start && end > w.virtStart) { @@ -1141,8 +1141,8 @@ var dragSelect = { var ce = e - w.virtStart + w.winStart; if (nonVirtChrom === "") { nonVirtChrom = w.chromName; - nonVirtStart = cs; - nonVirtEnd = ce; + nonVirtStart = cs; + nonVirtEnd = ce; } else { if (w.chromName === nonVirtChrom) { nonVirtEnd = Math.max(ce, nonVirtEnd); @@ -1153,9 +1153,9 @@ var dragSelect = { } } if (nonVirtChrom !== "") - cartSettings.nonVirtHighlight = makeHighlightString(getDb(), nonVirtChrom, nonVirtStart, (nonVirtEnd + 1), hlColorName); + cartSettings.nonVirtHighlight = makeHighlightString(getDb(), nonVirtChrom, nonVirtStart, (nonVirtEnd+1), hlColorName); } else if (hgTracks.windows && hgTracks.virtualSingleChrom) { - cartSettings.nonVirtHighlight = hgTracks.highlight; + cartSettings.nonVirtHighlight = hgTracks.highlight; } // TODO if not virt, do we need to erase cart nonVirtHighlight ? cart.setVarsObj(cartSettings); @@ -1163,46 +1163,46 @@ var dragSelect = { }, selectionEndDialog: function (newPosition) - // Let user choose between zoom-in and highlighting. - { + // Let user choose between zoom-in and highlighting. + { newPosition.replace("virt:", "multi:"); // if the user hit Escape just before, do not show this dialo - if (dragSelect.startTime === null) + if (dragSelect.startTime===null) return; var dragSelectDialog = $("#dragSelectDialog")[0]; if (!dragSelectDialog) { - $("body").append("
" + - "

"); + $("body").append("
" + + "

"); makeHighlightPicker("hlColor", document.getElementById("dragSelectDialog"), null); - $("#dragSelectDialog").append("
" + - "Don't show this again and always zoom with shift.
" + - "Re-enable via 'View - Configure Browser' (c then f)
" + - "Selected chromosome position: "); + $("#dragSelectDialog").append("
" + + "Don't show this again and always zoom with shift.
" + + "Re-enable via 'View - Configure Browser' (c then f)
"+ + "Selected chromosome position: "); dragSelectDialog = $("#dragSelectDialog")[0]; // reset value // allow to click checkbox by clicking on the label $('#hlNotShowAgainMsg').on("click", function() { $('#disableDragHighlight').trigger("click");}); // click "add highlight" when enter is pressed in color input box - $("#hlColorInput").on("keyup", function (event) { - if (event.keyCode == 13) { + $("#hlColorInput").on("keyup", function(event){ + if(event.keyCode == 13){ $(".ui-dialog-buttonset button:nth-child(3)").trigger("click"); } }); } if (hgTracks.windows) { - var i, len; + var i,len; var newerPosition = newPosition; - if (hgTracks.virtualSingleChrom && (newPosition.search("multi:") === 0)) { + if (hgTracks.virtualSingleChrom && (newPosition.search("multi:")===0)) { newerPosition = genomePos.disguisePosition(newPosition); } var str = newerPosition + "
\n"; @@ -1212,7 +1212,7 @@ var dragSelect = { var start = pos.start - 1; var end = pos.end; var selectedRegions = 0; - for (i = 0, len = hgTracks.windows.length; i < len; ++i) { + for (i=0,len=hgTracks.windows.length; i < len; ++i) { var w = hgTracks.windows[i]; // overlap with new position? if (w.virtEnd > start && end > w.virtStart) { @@ -1220,7 +1220,7 @@ var dragSelect = { var e = Math.min(end, w.virtEnd); var cs = s - w.virtStart + w.winStart; var ce = e - w.virtStart + w.winStart; - str2 += "
  • " + w.chromName + ":" + (cs + 1) + "-" + ce + "
  • \n"; + str2 += "
  • " + w.chromName + ":" + (cs+1) + "-" + ce + "
  • \n"; selectedRegions += 1; } } @@ -1233,81 +1233,81 @@ var dragSelect = { $("#dragSelectPosition").html(newPosition); } $(dragSelectDialog).dialog({ - modal: true, - title: "Drag-and-select", - closeOnEscape: true, - resizable: false, - autoOpen: false, - revertToOriginalPos: true, - minWidth: 550, - buttons: { - "Zoom In": function () { - // Zoom to selection - $(this).dialog("option", "revertToOriginalPos", false); - if ($("#disableDragHighlight").prop('checked')) - hgTracks.enableHighlightingDialog = false; - if (imageV2.inPlaceUpdate) { - if (hgTracks.virtualSingleChrom && (newPosition.search("multi:") === 0)) { - newPosition = genomePos.disguisePosition(newPosition); // DISGUISE + modal: true, + title: "Drag-and-select", + closeOnEscape: true, + resizable: false, + autoOpen: false, + revertToOriginalPos: true, + minWidth: 550, + buttons: { + "Zoom In": function() { + // Zoom to selection + $(this).dialog("option", "revertToOriginalPos", false); + if ($("#disableDragHighlight").prop('checked')) + hgTracks.enableHighlightingDialog = false; + if (imageV2.inPlaceUpdate) { + if (hgTracks.virtualSingleChrom && (newPosition.search("multi:")===0)) { + newPosition = genomePos.disguisePosition(newPosition); // DISGUISE + } + var params = "db=" + getDb() + "&position=" + newPosition; + if (!hgTracks.enableHighlightingDialog) + params += "&enableHighlightingDialog=0"; + imageV2.navigateInPlace(params, null, true); + } else { + $('body').css('cursor', 'wait'); + if (!hgTracks.enableHighlightingDialog) + cart.setVarsObj({'enableHighlightingDialog': 0 },null,false); // async=false + document.TrackHeaderForm.submit(); } - var params = "db=" + getDb() + "&position=" + newPosition; - if (!hgTracks.enableHighlightingDialog) - params += "&enableHighlightingDialog=0"; - imageV2.navigateInPlace(params, null, true); - } else { - $('body').css('cursor', 'wait'); - if (!hgTracks.enableHighlightingDialog) - cart.setVarsObj({'enableHighlightingDialog': 0}, null, false); // async=false - document.TrackHeaderForm.submit(); + $(this).dialog("close"); + }, + "Single Highlight": function() { + // Clear old highlight and Highlight selection + $(imageV2.imgTbl).imgAreaSelect({hide:true}); + if ($("#disableDragHighlight").prop('checked')) + hgTracks.enableHighlightingDialog = false; + var hlColor = $("#hlColorInput").val(); + dragSelect.highlightThisRegion(newPosition, false, hlColor); + $(this).dialog("close"); + }, + "Add Highlight": function() { + // Highlight selection + if ($("#disableDragHighlight").prop('checked')) + hgTracks.enableHighlightingDialog = false; + var hlColor = $("#hlColorInput").val(); + dragSelect.highlightThisRegion(newPosition, true, hlColor); + $(this).dialog("close"); + }, + "Save Color": function() { + var hlColor = $("#hlColorInput").val(); + dragSelect.saveHlColor( hlColor ); + $(this).dialog("close"); + }, + "Cancel": function() { + $(this).dialog("close"); } - $(this).dialog("close"); }, - "Single Highlight": function () { - // Clear old highlight and Highlight selection - $(imageV2.imgTbl).imgAreaSelect({hide: true}); - if ($("#disableDragHighlight").prop('checked')) - hgTracks.enableHighlightingDialog = false; - var hlColor = $("#hlColorInput").val(); - dragSelect.highlightThisRegion(newPosition, false, hlColor); - $(this).dialog("close"); + + open: function () { // Make zoom the focus/default action + $(this).parents('.ui-dialog-buttonpane button:eq(0)').trigger("focus"); }, - "Add Highlight": function () { - // Highlight selection + + close: function() { + // All exits to dialog should go through this + $(imageV2.imgTbl).imgAreaSelect({hide:true}); + if ($(this).dialog("option", "revertToOriginalPos")) + genomePos.revertToOriginalPos(); if ($("#disableDragHighlight").prop('checked')) - hgTracks.enableHighlightingDialog = false; - var hlColor = $("#hlColorInput").val(); - dragSelect.highlightThisRegion(newPosition, true, hlColor); - $(this).dialog("close"); - }, - "Save Color": function () { - var hlColor = $("#hlColorInput").val(); - dragSelect.saveHlColor(hlColor); - $(this).dialog("close"); - }, - "Cancel": function () { - $(this).dialog("close"); + $(this).remove(); + else + $(this).hide(); + $('body').css('cursor', ''); // Occasionally wait cursor got left behind + $("#hlColorPicker").spectrum("hide"); } - }, - - open: function () { // Make zoom the focus/default action - $(this).parents('.ui-dialog-buttonpane button:eq(0)').trigger("focus"); - }, - - close: function () { - // All exits to dialog should go through this - $(imageV2.imgTbl).imgAreaSelect({hide: true}); - if ($(this).dialog("option", "revertToOriginalPos")) - genomePos.revertToOriginalPos(); - if ($("#disableDragHighlight").prop('checked')) - $(this).remove(); - else - $(this).hide(); - $('body').css('cursor', ''); // Occasionally wait cursor got left behind - $("#hlColorPicker").spectrum("hide"); - } }); $(dragSelectDialog).dialog('open'); - + }, selectEnd: function (img, selection, event) @@ -1329,25 +1329,25 @@ var dragSelect = { if (doIt) { // dragSelect.startTime is null if mouse has never been moved - var singleClick = ((selection.x2 === selection.x1) - || dragSelect.startTime === null - || (now.getTime() - dragSelect.startTime) < 100); + var singleClick = ( (selection.x2 === selection.x1) + || dragSelect.startTime === null + || (now.getTime() - dragSelect.startTime) < 100); var newPosition = genomePos.update(img, selection, singleClick); newPosition.replace("virt:", "multi:"); if (newPosition) { if (event.altKey) { // with the alt-key, only highlight the region, do not zoom dragSelect.highlightThisRegion(newPosition, true); - $(imageV2.imgTbl).imgAreaSelect({hide: true}); + $(imageV2.imgTbl).imgAreaSelect({hide:true}); } else { if (hgTracks.enableHighlightingDialog && !(event.metaKey || event.ctrlKey)) // don't show the dialog if: clicked on ruler, if dialog deactivated or meta/ctrl was pressed dragSelect.selectionEndDialog(newPosition); else { // in every other case, show the dialog - $(imageV2.imgTbl).imgAreaSelect({hide: true}); + $(imageV2.imgTbl).imgAreaSelect({hide:true}); if (imageV2.inPlaceUpdate) { - if (hgTracks.virtualSingleChrom && (newPosition.search("multi:") === 0)) { + if (hgTracks.virtualSingleChrom && (newPosition.search("multi:")===0)) { newPosition = genomePos.disguisePosition(newPosition); // DISGUISE } imageV2.navigateInPlace("db=" + getDb() + "&position=" + newPosition, null, true); @@ -1358,12 +1358,12 @@ var dragSelect = { } } } else { - $(imageV2.imgTbl).imgAreaSelect({hide: true}); + $(imageV2.imgTbl).imgAreaSelect({hide:true}); genomePos.revertToOriginalPos(); } dragSelect.startTime = null; // blockMapClicks/allowMapClicks() is necessary if selectEnd was over a map item. - setTimeout(posting.allowMapClicks, 50); + setTimeout(posting.allowMapClicks,50); return true; } }, @@ -1373,10 +1373,10 @@ var dragSelect = { var imgHeight = 0; if (imageV2.enabled) imgHeight = imageV2.imgTbl.innerHeight() - 1; // last little bit makes border look ok - + // No longer disable without ruler, because shift-drag still works - if (typeof (hgTracks) !== "undefined") { + if (typeof(hgTracks) !== "undefined") { if (hgTracks.rulerClickHeight === undefined || hgTracks.rulerClickHeight === null) hgTracks.rulerClickHeight = 0; // will be zero if no ruler track @@ -1385,32 +1385,32 @@ var dragSelect = { var xLimits = genomePos.getXLimits($(imageV2.imgTbl), 0); dragSelect.areaSelector = jQuery((imageV2.imgTbl).imgAreaSelect({ - minX: xLimits[0], - maxX: xLimits[1], - selectionColor: 'blue', - outerColor: '', - minHeight: imgHeight, - maxHeight: imgHeight, - onSelectStart: dragSelect.selectStart, - onSelectChange: dragSelect.selectChange, - onSelectEnd: dragSelect.selectEnd, - autoHide: false, // gets hidden after possible dialog - movable: false, + minX : xLimits[0], + maxX : xLimits[1], + selectionColor: 'blue', + outerColor: '', + minHeight: imgHeight, + maxHeight: imgHeight, + onSelectStart: dragSelect.selectStart, + onSelectChange: dragSelect.selectChange, + onSelectEnd: dragSelect.selectEnd, + autoHide: false, // gets hidden after possible dialog + movable: false, clickClipHeight: heights })); // remove any ongoing drag-selects when the esc key is pressed anywhere for this document // This allows to abort zooming / highlighting - $(document).on("keyup", function (e) { - if (e.keyCode === 27) { - $(imageV2.imgTbl).imgAreaSelect({hide: true}); + $(document).on("keyup", function(e){ + if(e.keyCode === 27) { + $(imageV2.imgTbl).imgAreaSelect({hide:true}); dragSelect.escPressed = true; } }); // hide and redraw all current highlights when the browser window is resized - $(window).on("resize", function () { - $(imageV2.imgTbl).imgAreaSelect({hide: true}); + $(window).on("resize", function() { + $(imageV2.imgTbl).imgAreaSelect({hide:true}); imageV2.drawHighlights(); }); @@ -1418,525 +1418,525 @@ var dragSelect = { } }; + ///////////////////////////////////// + //// Chrom Drag/Zoom/Expand code //// ///////////////////////////////////// -//// Chrom Drag/Zoom/Expand code //// -///////////////////////////////////// -jQuery.fn.chromDrag = function () { - this.each(function () { - // Plan: - // mouseDown: determine where in map: convert to img location: pxDown - // mouseMove: flag drag - // mouseUp: if no drag, then create href centered on bpDown loc with current span - // if drag, then create href from bpDown to bpUp - // if ctrlKey then expand selection to containing cytoBand(s) - - // Image dimensions all in pix - var img = {top: -1, scrolledTop: -1, height: -1, left: -1, scrolledLeft: -1, width: -1}; - // chrom Dimensions beg,end,size in bases, rest in pix - var chr = { name: "", reverse: false, beg: -1, end: -1, size: -1, - top: -1, bottom: -1, left: -1, right: -1, width: -1 }; - var pxDown = 0; // pix X location of mouseDown - var chrImg = $(this); - var mouseIsDown = false; - var mouseHasMoved = false; - var hilite = null; - - initialize(); - - function initialize() { - - findDimensions(); - - if (chr.top === -1) - warn("chromIdeo(): failed to register " + this.id); - else { - hiliteSetup(); - - $('area.cytoBand').off('mousedown'); // Make sure this is only bound once - $('area.cytoBand').on("mousedown", function(e) - { // mousedown on chrom portion of image only (map items) - updateImgOffsets(); - pxDown = e.clientX - img.scrolledLeft; - var pxY = e.clientY - img.scrolledTop; - if (mouseIsDown === false - && isWithin(chr.left, pxDown, chr.right) && isWithin(chr.top, pxY, chr.bottom)) { - mouseIsDown = true; - mouseHasMoved = false; - - $(document).on('mousemove', chromMove); - $(document).on('mouseup', chromUp); - hiliteShow(pxDown, pxDown); - return false; - } - }); - } - } +jQuery.fn.chromDrag = function(){ +this.each(function(){ + // Plan: + // mouseDown: determine where in map: convert to img location: pxDown + // mouseMove: flag drag + // mouseUp: if no drag, then create href centered on bpDown loc with current span + // if drag, then create href from bpDown to bpUp + // if ctrlKey then expand selection to containing cytoBand(s) + + // Image dimensions all in pix + var img = { top: -1, scrolledTop: -1, height: -1, left: -1, scrolledLeft: -1, width: -1 }; + // chrom Dimensions beg,end,size in bases, rest in pix + var chr = { name: "", reverse: false, beg: -1, end: -1, size: -1, + top: -1, bottom: -1, left: -1, right: -1, width: -1 }; + var pxDown = 0; // pix X location of mouseDown + var chrImg = $(this); + var mouseIsDown = false; + var mouseHasMoved = false; + var hilite = null; + + initialize(); + + function initialize(){ + + findDimensions(); + + if (chr.top === -1) + warn("chromIdeo(): failed to register "+this.id); + else { + hiliteSetup(); - function chromMove(e) - { // If mouse was down, determine if dragged, then show hilite - if (mouseIsDown) { - var pxX = e.clientX - img.scrolledLeft; - var relativeX = (pxX - pxDown); - if (mouseHasMoved || (mouseHasMoved === false && Math.abs(relativeX) > 2)) { - mouseHasMoved = true; - if (isWithin(chr.left, pxX, chr.right)) - hiliteShow(pxDown, pxX); - else if (pxX < chr.left) - hiliteShow(pxDown, chr.left); - else - hiliteShow(pxDown, chr.right); + $('area.cytoBand').off('mousedown'); // Make sure this is only bound once + $('area.cytoBand').on("mousedown", function(e) + { // mousedown on chrom portion of image only (map items) + updateImgOffsets(); + pxDown = e.clientX - img.scrolledLeft; + var pxY = e.clientY - img.scrolledTop; + if (mouseIsDown === false + && isWithin(chr.left,pxDown,chr.right) && isWithin(chr.top,pxY,chr.bottom)) { + mouseIsDown = true; + mouseHasMoved = false; + + $(document).on('mousemove',chromMove); + $(document).on( 'mouseup', chromUp); + hiliteShow(pxDown,pxDown); + return false; } + }); + } + } + + function chromMove(e) + { // If mouse was down, determine if dragged, then show hilite + if ( mouseIsDown ) { + var pxX = e.clientX - img.scrolledLeft; + var relativeX = (pxX - pxDown); + if (mouseHasMoved || (mouseHasMoved === false && Math.abs(relativeX) > 2)) { + mouseHasMoved = true; + if (isWithin(chr.left,pxX,chr.right)) + hiliteShow(pxDown,pxX); + else if (pxX < chr.left) + hiliteShow(pxDown,chr.left); + else + hiliteShow(pxDown,chr.right); } } - function chromUp(e) - { // If mouse was down, handle final selection - $(document).off('mousemove', chromMove); - $(document).off('mouseup', chromUp); - chromMove(e); // Just in case - if (mouseIsDown) { - updateImgOffsets(); - var bands; - var pxUp = e.clientX - img.scrolledLeft; - var pxY = e.clientY - img.scrolledTop; - if (isWithin(0, pxY, img.height)) { // within vertical range or else cancel - var selRange = {beg: -1, end: -1, width: -1}; - var dontAsk = true; - - if (e.ctrlKey) { - bands = findCytoBand(pxDown, pxUp); - if (bands.end > -1) { - pxDown = bands.left; - pxUp = bands.right; - mouseHasMoved = true; - dontAsk = false; - selRange.beg = bands.beg; - selRange.end = bands.end; - hiliteShow(pxDown, pxUp); - } + } + function chromUp(e) + { // If mouse was down, handle final selection + $(document).off('mousemove',chromMove); + $(document).off('mouseup',chromUp); + chromMove(e); // Just in case + if (mouseIsDown) { + updateImgOffsets(); + var bands; + var pxUp = e.clientX - img.scrolledLeft; + var pxY = e.clientY - img.scrolledTop; + if (isWithin(0,pxY,img.height)) { // within vertical range or else cancel + var selRange = { beg: -1, end: -1, width: -1 }; + var dontAsk = true; + + if (e.ctrlKey) { + bands = findCytoBand(pxDown,pxUp); + if (bands.end > -1) { + pxDown = bands.left; + pxUp = bands.right; + mouseHasMoved = true; + dontAsk = false; + selRange.beg = bands.beg; + selRange.end = bands.end; + hiliteShow(pxDown,pxUp); } - else if (mouseHasMoved) { - // bounded by chrom dimensions: but must remain within image! - if (isWithin(-20, pxUp, chr.left)) - pxUp = chr.left; - if (isWithin(chr.right, pxUp, img.width + 20)) - pxUp = chr.right; + } + else if (mouseHasMoved) { + // bounded by chrom dimensions: but must remain within image! + if (isWithin(-20,pxUp,chr.left)) + pxUp = chr.left; + if (isWithin(chr.right,pxUp,img.width + 20)) + pxUp = chr.right; - if (isWithin(chr.left, pxUp, chr.right + 1)) { + if ( isWithin(chr.left,pxUp,chr.right+1) ) { - selRange.beg = convertToBases(pxDown); - selRange.end = convertToBases(pxUp); + selRange.beg = convertToBases(pxDown); + selRange.end = convertToBases(pxUp); - if (Math.abs(selRange.end - selRange.beg) < 20) - mouseHasMoved = false; // Drag so small: treat as simple click - else - dontAsk = false; - } + if (Math.abs(selRange.end - selRange.beg) < 20) + mouseHasMoved = false; // Drag so small: treat as simple click + else + dontAsk = false; } - if (mouseHasMoved === false) { // Not else because small drag turns this off + } + if (mouseHasMoved === false) { // Not else because small drag turns this off - hiliteShow(pxUp, pxUp); - var curWidth = hgTracks.winEnd - hgTracks.winStart; - // Notice that beg is based upon up position - selRange.beg = convertToBases(pxUp) - Math.round(curWidth / 2); - selRange.end = selRange.beg + curWidth; + hiliteShow(pxUp,pxUp); + var curWidth = hgTracks.winEnd - hgTracks.winStart; + // Notice that beg is based upon up position + selRange.beg = convertToBases(pxUp) - Math.round(curWidth/2); + selRange.end = selRange.beg + curWidth; + } + if (selRange.end > -1) { + // prompt, then submit for new position + selRange = rangeNormalizeToChrom(selRange,chr); + if (mouseHasMoved === false) { // Update highlight by converting bp back to pix + pxDown = convertFromBases(selRange.beg); + pxUp = convertFromBases(selRange.end); + hiliteShow(pxDown,pxUp); } - if (selRange.end > -1) { - // prompt, then submit for new position - selRange = rangeNormalizeToChrom(selRange, chr); - if (mouseHasMoved === false) { // Update highlight by converting bp back to pix - pxDown = convertFromBases(selRange.beg); - pxUp = convertFromBases(selRange.end); - hiliteShow(pxDown, pxUp); - } - //if ((selRange.end - selRange.beg) < 50000) - // dontAsk = true; - if (dontAsk - || confirm("Jump to new position:\n\n" + chr.name + ":" + commify(selRange.beg) + - "-" + commify(selRange.end) + " size:" + commify(selRange.width))) { - genomePos.setByCoordinates(chr.name, selRange.beg, selRange.end); - // Stop the presses :0) - $('area.cytoBand').on("mousedown", function(e) { return false; }); - if (imageV2.backSupport) { - imageV2.navigateInPlace("db=" + getDb() + "&position=" + - encodeURIComponent(genomePos.get().replace(/,/g, '')) + - "&findNearest=1", null, true); - hiliteCancel(); - } else - document.TrackHeaderForm.submit(); - return true; // Make sure the setTimeout below is not called. - } + //if ((selRange.end - selRange.beg) < 50000) + // dontAsk = true; + if (dontAsk + || confirm("Jump to new position:\n\n"+chr.name+":"+commify(selRange.beg)+ + "-"+commify(selRange.end)+" size:"+commify(selRange.width)) ) { + genomePos.setByCoordinates(chr.name, selRange.beg, selRange.end); + // Stop the presses :0) + $('area.cytoBand').on("mousedown", function(e) { return false; }); + if (imageV2.backSupport) { + imageV2.navigateInPlace("db=" + getDb() + "&position=" + + encodeURIComponent(genomePos.get().replace(/,/g,'')) + + "&findNearest=1",null,true); + hiliteCancel(); + } else + document.TrackHeaderForm.submit(); + return true; // Make sure the setTimeout below is not called. } } - hiliteCancel(); - setTimeout(posting.allowMapClicks, 50); } - mouseIsDown = false; - mouseHasMoved = false; + hiliteCancel(); + setTimeout(posting.allowMapClicks,50); } + mouseIsDown = false; + mouseHasMoved = false; + } - function isWithin(beg,here,end) - { // Simple utility - return (beg <= here && here < end); - } - function convertToBases(pxX) - { // Simple utility to convert pix to bases - var offset = (pxX - chr.left) / chr.width; - if (chr.reverse) - offset = 1 - offset; - return Math.round(offset * chr.size); - } - function convertFromBases(bases) - { // Simple utility to convert bases to pix - var offset = bases / chr.size; - if (chr.reverse) - offset = 1 - offset; - return Math.round(offset * chr.width) + chr.left; - } + function isWithin(beg,here,end) + { // Simple utility + return ( beg <= here && here < end ); + } + function convertToBases(pxX) + { // Simple utility to convert pix to bases + var offset = (pxX - chr.left)/chr.width; + if (chr.reverse) + offset = 1 - offset; + return Math.round(offset * chr.size); + } + function convertFromBases(bases) + { // Simple utility to convert bases to pix + var offset = bases/chr.size; + if (chr.reverse) + offset = 1 - offset; + return Math.round(offset * chr.width) + chr.left; + } - function findDimensions() - { // Called at init: determine the dimensions of chrom from 'cytoband' map items - var lastX = -1; - $('area.cytoBand').each(function (ix) { - var loc = this.coords.split(","); - if (loc.length === 4) { - var myLeft = parseInt(loc[0]); - var myRight = parseInt(loc[2]); - if (chr.top === -1) { - chr.left = myLeft; - chr.right = myRight; - chr.top = parseInt(loc[1]); - chr.bottom = parseInt(loc[3]); - } else { - if (chr.left > myLeft) - chr.left = myLeft; - if (chr.right < parseInt(loc[2])) - chr.right = parseInt(loc[2]); - } + function findDimensions() + { // Called at init: determine the dimensions of chrom from 'cytoband' map items + var lastX = -1; + $('area.cytoBand').each(function(ix) { + var loc = this.coords.split(","); + if (loc.length === 4) { + var myLeft = parseInt(loc[0]); + var myRight = parseInt(loc[2]); + if (chr.top === -1) { + chr.left = myLeft; + chr.right = myRight; + chr.top = parseInt(loc[1]); + chr.bottom = parseInt(loc[3]); + } else { + if (chr.left > myLeft) + chr.left = myLeft; + if (chr.right < parseInt(loc[2])) + chr.right = parseInt(loc[2]); + } - var range = this.title.substr(this.title.lastIndexOf(':') + 1); - var pos = range.split('-'); - if (pos.length === 2) { - if (chr.name.length === 0) { + var range = this.title.substr(this.title.lastIndexOf(':')+1); + var pos = range.split('-'); + if (pos.length === 2) { + if (chr.name.length === 0) { + chr.beg = parseInt(pos[0]); + //chr.end = parseInt(pos[1]); + chr.name = this.title.substring(this.title.lastIndexOf(' ')+1, + this.title.lastIndexOf(':')); + } else { + if (chr.beg > parseInt(pos[0])) chr.beg = parseInt(pos[0]); - //chr.end = parseInt(pos[1]); - chr.name = this.title.substring(this.title.lastIndexOf(' ') + 1, - this.title.lastIndexOf(':')); - } else { - if (chr.beg > parseInt(pos[0])) - chr.beg = parseInt(pos[0]); - } - if (chr.end < parseInt(pos[1])) { - chr.end = parseInt(pos[1]); - if (lastX === -1) - lastX = myRight; - else if (lastX > myRight) - chr.reverse = true; // end is advancing, but X is not, so reverse - } else if (lastX !== -1 && lastX < myRight) - chr.reverse = true; // end is not advancing, but X is, so reverse - } - $(this).css('cursor', 'text'); - $(this).attr("href", ""); + if (chr.end < parseInt(pos[1])) { + chr.end = parseInt(pos[1]); + if (lastX === -1) + lastX = myRight; + else if (lastX > myRight) + chr.reverse = true; // end is advancing, but X is not, so reverse + } else if (lastX !== -1 && lastX < myRight) + chr.reverse = true; // end is not advancing, but X is, so reverse + } - }); - chr.size = (chr.end - chr.beg); - chr.width = (chr.right - chr.left); - } + $(this).css( 'cursor', 'text'); + $(this).attr("href",""); + } + }); + chr.size = (chr.end - chr.beg ); + chr.width = (chr.right - chr.left); + } - function findCytoBand(pxDown,pxUp) - { // Called when mouseup and ctrl: Find the bounding cytoband dimensions (in pix and bases) - var cyto = {left: -1, right: -1, beg: -1, end: -1}; - $('area.cytoBand').each(function (ix) { - var loc = this.coords.split(","); - if (loc.length === 4) { - var myLeft = parseInt(loc[0]); - var myRight = parseInt(loc[2]); - var range; - var pos; - if (cyto.left === -1 || cyto.left > myLeft) { - if (isWithin(myLeft, pxDown, myRight) || isWithin(myLeft, pxUp, myRight)) { - cyto.left = myLeft; - range = this.title.substr(this.title.lastIndexOf(':') + 1); - pos = range.split('-'); - if (pos.length === 2) { - cyto.beg = (chr.reverse ? parseInt(pos[1]) : parseInt(pos[0])); - } + function findCytoBand(pxDown,pxUp) + { // Called when mouseup and ctrl: Find the bounding cytoband dimensions (in pix and bases) + var cyto = { left: -1, right: -1, beg: -1, end: -1 }; + $('area.cytoBand').each(function(ix) { + var loc = this.coords.split(","); + if (loc.length === 4) { + var myLeft = parseInt(loc[0]); + var myRight = parseInt(loc[2]); + var range; + var pos; + if (cyto.left === -1 || cyto.left > myLeft) { + if ( isWithin(myLeft,pxDown,myRight) || isWithin(myLeft,pxUp,myRight) ) { + cyto.left = myLeft; + range = this.title.substr(this.title.lastIndexOf(':')+1); + pos = range.split('-'); + if (pos.length === 2) { + cyto.beg = (chr.reverse ? parseInt(pos[1]) : parseInt(pos[0])); } } - if (cyto.right === -1 || cyto.right < myRight) { - if (isWithin(myLeft, pxDown, myRight) || isWithin(myLeft, pxUp, myRight)) { - cyto.right = myRight; - range = this.title.substr(this.title.lastIndexOf(':') + 1); - pos = range.split('-'); - if (pos.length === 2) { - cyto.end = (chr.reverse ? parseInt(pos[0]) : parseInt(pos[1])); - } + } + if (cyto.right === -1 || cyto.right < myRight) { + if ( isWithin(myLeft,pxDown,myRight) || isWithin(myLeft,pxUp,myRight) ) { + cyto.right = myRight; + range = this.title.substr(this.title.lastIndexOf(':')+1); + pos = range.split('-'); + if (pos.length === 2) { + cyto.end = (chr.reverse ? parseInt(pos[0]) : parseInt(pos[1])); } } } - }); - return cyto; - } - function rangeNormalizeToChrom(selection,chrom) - { // Called before presenting or using base range: make sure chrom selection - // is within chrom range - if (selection.end < selection.beg) { - var tmp = selection.end; - selection.end = selection.beg; - selection.beg = tmp; - } - selection.width = (selection.end - selection.beg); - selection.beg += 1; - if (selection.beg < chrom.beg) { - selection.beg = chrom.beg; - selection.end = chrom.beg + selection.width; } - if (selection.end > chrom.end) { - selection.end = chrom.end; - selection.beg = chrom.end - selection.width; - if (selection.beg < chrom.beg) { // spans whole chrom - selection.width = (selection.end - chrom.beg); - selection.beg = chrom.beg + 1; - } - } - return selection; - } - - function hiliteShow(down,cur) - { // Called on mousemove, mouseup: set drag hilite dimensions - var topY = img.top; - var high = img.height; - var begX = -1; - var wide = -1; - if (cur < down) { - begX = cur + img.left; - wide = (down - cur); - } else { - begX = down + img.left; - wide = (cur - down); - } - $(hilite).css({ left: begX + 'px', width: wide + 'px', top: topY + 'px', - height: high + 'px', display:'' }); - $(hilite).show(); - } - function hiliteCancel(left,width,top,height) - { // Called on mouseup: Make green drag hilite disappear when no longer wanted - $(hilite).hide(); - $(hilite).css({left: '0px', width: '0px', top: '0px', height: '0px'}); - } - - function hiliteSetup() - { // Called on init: setup of drag region hilite (but don't show yet) - if (hilite === null) { // setup only once - hilite = jQuery("
    "); - $(hilite).css({ backgroundColor: 'green', opacity: 0.4, borderStyle: 'solid', - borderWidth: '1px', bordercolor: '#0000FF' }); - $(hilite).css({display: 'none', position: 'absolute', overflow: 'hidden', zIndex: 1}); - jQuery($(chrImg).parents('body')).append($(hilite)); - } - return hilite; - } - - function updateImgOffsets() - { // Called on mousedown: Gets the current offsets - var offs = $(chrImg).offset(); - img.top = Math.round(offs.top); - img.left = Math.round(offs.left); - img.scrolledTop = img.top - $("body").scrollTop(); - img.scrolledLeft = img.left - $("body").scrollLeft(); - if (theClient.isIePre11()) { - img.height = $(chrImg).outerHeight(); - img.width = $(chrImg).outerWidth(); - } else { - img.height = $(chrImg).height(); - img.width = $(chrImg).width(); + }); + return cyto; + } + function rangeNormalizeToChrom(selection,chrom) + { // Called before presenting or using base range: make sure chrom selection + // is within chrom range + if (selection.end < selection.beg) { + var tmp = selection.end; + selection.end = selection.beg; + selection.beg = tmp; + } + selection.width = (selection.end - selection.beg); + selection.beg += 1; + if (selection.beg < chrom.beg) { + selection.beg = chrom.beg; + selection.end = chrom.beg + selection.width; + } + if (selection.end > chrom.end) { + selection.end = chrom.end; + selection.beg = chrom.end - selection.width; + if (selection.beg < chrom.beg) { // spans whole chrom + selection.width = (selection.end - chrom.beg); + selection.beg = chrom.beg + 1; } - return img; } - }); + return selection; + } + + function hiliteShow(down,cur) + { // Called on mousemove, mouseup: set drag hilite dimensions + var topY = img.top; + var high = img.height; + var begX = -1; + var wide = -1; + if (cur < down) { + begX = cur + img.left; + wide = (down - cur); + } else { + begX = down + img.left; + wide = (cur - down); + } + $(hilite).css({ left: begX + 'px', width: wide + 'px', top: topY + 'px', + height: high + 'px', display:'' }); + $(hilite).show(); + } + function hiliteCancel(left,width,top,height) + { // Called on mouseup: Make green drag hilite disappear when no longer wanted + $(hilite).hide(); + $(hilite).css({ left: '0px', width: '0px', top: '0px', height: '0px' }); + } + + function hiliteSetup() + { // Called on init: setup of drag region hilite (but don't show yet) + if (hilite === null) { // setup only once + hilite = jQuery("
    "); + $(hilite).css({ backgroundColor: 'green', opacity: 0.4, borderStyle: 'solid', + borderWidth: '1px', bordercolor: '#0000FF' }); + $(hilite).css({ display: 'none', position: 'absolute', overflow: 'hidden', zIndex: 1 }); + jQuery($(chrImg).parents('body')).append($(hilite)); + } + return hilite; + } + + function updateImgOffsets() + { // Called on mousedown: Gets the current offsets + var offs = $(chrImg).offset(); + img.top = Math.round(offs.top ); + img.left = Math.round(offs.left); + img.scrolledTop = img.top - $("body").scrollTop(); + img.scrolledLeft = img.left - $("body").scrollLeft(); + if (theClient.isIePre11()) { + img.height = $(chrImg).outerHeight(); + img.width = $(chrImg).outerWidth(); + } else { + img.height = $(chrImg).height(); + img.width = $(chrImg).width(); + } + return img; + } +}); }; + ////////////////////////// + //// Drag Scroll code //// ////////////////////////// -//// Drag Scroll code //// -////////////////////////// -jQuery.fn.panImages = function () { +jQuery.fn.panImages = function(){ // globals across all panImages genomePos.original = genomePos.getOriginalPos(); // redundant but makes certain original is set. - var leftLimit = hgTracks.imgBoxLeftLabel * -1; - var rightLimit = (hgTracks.imgBoxPortalWidth - hgTracks.imgBoxWidth + leftLimit); + var leftLimit = hgTracks.imgBoxLeftLabel * -1; + var rightLimit = (hgTracks.imgBoxPortalWidth - hgTracks.imgBoxWidth + leftLimit); var only1xScrolling = ((hgTracks.imgBoxWidth - hgTracks.imgBoxPortalWidth) === 0); - var prevX = (hgTracks.imgBoxPortalOffsetX + hgTracks.imgBoxLeftLabel) * -1; + var prevX = (hgTracks.imgBoxPortalOffsetX + hgTracks.imgBoxLeftLabel) * -1; var portalWidth = 0; var portalAbsoluteX = 0; var savedPosition; - var highlightAreas = null; // Used to ensure dragSelect highlight will scroll. + var highlightAreas = null; // Used to ensure dragSelect highlight will scroll. - this.each(function () { + this.each(function(){ - var pic; - var pan; + var pic; + var pan; - if ($(this).is("img")) { - pan = $(this).parent("div"); - pic = $(this); - } - else if ( $(this).is("div.scroller") ) { - pan = $(this); - pic = $(this).children("img#panImg"); // Get the real pic - } - - if (!pan || !pic) { - throw "Not a div with child image! 'panImages' can only be used with divs contain images."; - } - - // globals across all panImages - portalWidth = $(pan).width(); - portalAbsoluteX = $(pan).offset().left; - // globals to one panImage - var newX = 0; - var mouseDownX = 0; - var mouseIsDown = false; - var beyondImage = false; - var atEdge = false; - - initialize(); + if ( $(this).is("img") ) { + pan = $(this).parent("div"); + pic = $(this); + } + else if ( $(this).is("div.scroller") ) { + pan = $(this); + pic = $(this).children("img#panImg"); // Get the real pic + } - function initialize() { + if (!pan || !pic) { + throw "Not a div with child image! 'panImages' can only be used with divs contain images."; + } - $(pan).parents('td.tdData').on("mousemove", function (e) { - if (e.shiftKey) - $(this).css('cursor', "crosshair"); // shift-dragZoom - else if (theClient.isIePre11()) // IE will override map item cursors if this gets set - $(this).css('cursor', ""); // normal pointer when not over clickable item - }); + // globals across all panImages + portalWidth = $(pan).width(); + portalAbsoluteX = $(pan).offset().left; + // globals to one panImage + var newX = 0; + var mouseDownX = 0; + var mouseIsDown = false; + var beyondImage = false; + var atEdge = false; + + initialize(); + + function initialize(){ + + $(pan).parents('td.tdData').on("mousemove", function(e) { + if (e.shiftKey) + $(this).css('cursor',"crosshair"); // shift-dragZoom + else if ( theClient.isIePre11() ) // IE will override map item cursors if this gets set + $(this).css('cursor',""); // normal pointer when not over clickable item + }); - panAdjustHeight(prevX); + panAdjustHeight(prevX); - pan.on("mousedown", function (e) { - if (e.which > 1 || e.button > 1 || e.shiftKey || e.metaKey || e.altKey || e.ctrlKey) - return true; - if (mouseIsDown === false) { - if (rightClick.menu) { - rightClick.menu.hide(); - } - mouseIsDown = true; - mouseDownX = e.clientX; - highlightAreas = $('.highlightItem'); - atEdge = (!beyondImage && (prevX >= leftLimit || prevX <= rightLimit)); - $(document).on('mousemove', panner); - $(document).on('mouseup', panMouseUp); // Will exec only once - return false; + pan.on("mousedown", function(e){ + if (e.which > 1 || e.button > 1 || e.shiftKey || e.metaKey || e.altKey || e.ctrlKey) + return true; + if (mouseIsDown === false) { + if (rightClick.menu) { + rightClick.menu.hide(); } - }); - } - - function panner(e) { - //if (!e) e = window.event; - if (mouseIsDown) { - var relativeX = (e.clientX - mouseDownX); + mouseIsDown = true; + mouseDownX = e.clientX; + highlightAreas = $('.highlightItem'); + atEdge = (!beyondImage && (prevX >= leftLimit || prevX <= rightLimit)); + $(document).on('mousemove',panner); + $(document).on('mouseup', panMouseUp); // Will exec only once + return false; + } + }); + } - if (relativeX !== 0) { - if (posting.mapClicksAllowed()) { - // need to throw up a z-index div. Wait mask? - savedPosition = genomePos.get(); - dragMaskShow(); - posting.blockMapClicks(); - } - var decelerator = 1; - //var wingSize = 1000; // 0 stops the scroll at the edges. - // Remeber that offsetX (prevX) is negative - newX = prevX + relativeX; - if (newX >= leftLimit) { // scrolled all the way to the left - if (atEdge) { // Do not drag straight off edge. Force second drag - beyondImage = true; - newX = leftLimit + (newX - leftLimit) / decelerator;// slower - //if (newX >= leftLimit + wingSize) // Don't go too far over the edge! - // newX = leftLimit + wingSize; - } else - newX = leftLimit; - - } else if (newX < rightLimit) { // scrolled all the way to the right - if (atEdge) { // Do not drag straight off edge. Force second drag - beyondImage = true; - newX = rightLimit - (rightLimit - newX) / decelerator;// slower - //if (newX < rightLimit - wingSize) // Don't go too far over the edge! - // newX = rightLimit - wingSize; - } else - newX = rightLimit; - - } else if (newX >= rightLimit && newX < leftLimit) - beyondImage = false; // could have scrolled back without mouse up - - posStatus = panUpdatePosition(newX, true); - newX = posStatus.newX; - // do not update highlights if we are at the end of a chromsome - if (!posStatus.isOutsideChrom) - scrollHighlight(relativeX); - - var nowPos = newX.toString() + "px"; - $(".panImg").css({'left': nowPos}); - $('.tdData').css({'backgroundPosition': nowPos}); - if (!only1xScrolling) - panAdjustHeight(newX); // Will dynamically resize image while scrolling. + function panner(e) { + //if (!e) e = window.event; + if ( mouseIsDown ) { + var relativeX = (e.clientX - mouseDownX); + + if (relativeX !== 0) { + if (posting.mapClicksAllowed()) { + // need to throw up a z-index div. Wait mask? + savedPosition = genomePos.get(); + dragMaskShow(); + posting.blockMapClicks(); } + var decelerator = 1; + //var wingSize = 1000; // 0 stops the scroll at the edges. + // Remeber that offsetX (prevX) is negative + newX = prevX + relativeX; + if ( newX >= leftLimit ) { // scrolled all the way to the left + if (atEdge) { // Do not drag straight off edge. Force second drag + beyondImage = true; + newX = leftLimit + (newX - leftLimit)/decelerator;// slower + //if (newX >= leftLimit + wingSize) // Don't go too far over the edge! + // newX = leftLimit + wingSize; + } else + newX = leftLimit; + + } else if ( newX < rightLimit ) { // scrolled all the way to the right + if (atEdge) { // Do not drag straight off edge. Force second drag + beyondImage = true; + newX = rightLimit - (rightLimit - newX)/decelerator;// slower + //if (newX < rightLimit - wingSize) // Don't go too far over the edge! + // newX = rightLimit - wingSize; + } else + newX = rightLimit; + + } else if (newX >= rightLimit && newX < leftLimit) + beyondImage = false; // could have scrolled back without mouse up + + posStatus = panUpdatePosition(newX,true); + newX = posStatus.newX; + // do not update highlights if we are at the end of a chromsome + if (!posStatus.isOutsideChrom) + scrollHighlight(relativeX); + + var nowPos = newX.toString() + "px"; + $(".panImg").css( {'left': nowPos }); + $('.tdData').css( {'backgroundPosition': nowPos } ); + if (!only1xScrolling) + panAdjustHeight(newX); // Will dynamically resize image while scrolling. } } - function panMouseUp(e) { // Must be a separate function instead of pan.mouseup event. - //if (!e) e = window.event; - if (mouseIsDown) { - - dragMaskClear(); - $(document).off('mousemove', panner); - $(document).off('mouseup', panMouseUp); - mouseIsDown = false; - // timeout incase the dragSelect.selectEnd was over a map item. select takes precedence. - setTimeout(posting.allowMapClicks, 50); - - // Outside image? Then abandon. - var curY = e.pageY; - var imgTbl = $('#imgTbl'); - var north = $(imgTbl).offset().top; - var south = north + $(imgTbl).height(); - if (curY < north || curY > south) { - atEdge = false; - beyondImage = false; - if (savedPosition) - genomePos.set(savedPosition); - var oldPos = prevX.toString() + "px"; - $(".panImg").css({'left': oldPos}); - $('.tdData').css({'backgroundPosition': oldPos}); - if (highlightAreas) - imageV2.drawHighlights(); - return true; - } + } + function panMouseUp(e) { // Must be a separate function instead of pan.mouseup event. + //if (!e) e = window.event; + if (mouseIsDown) { - // Do we need to fetch anything? - if (beyondImage) { - if (imageV2.inPlaceUpdate) { - var pos = parsePosition(genomePos.get()); - imageV2.navigateInPlace("db=" + getDb() + "&position=" + + dragMaskClear(); + $(document).off('mousemove',panner); + $(document).off('mouseup',panMouseUp); + mouseIsDown = false; + // timeout incase the dragSelect.selectEnd was over a map item. select takes precedence. + setTimeout(posting.allowMapClicks,50); + + // Outside image? Then abandon. + var curY = e.pageY; + var imgTbl = $('#imgTbl'); + var north = $(imgTbl).offset().top; + var south = north + $(imgTbl).height(); + if (curY < north || curY > south) { + atEdge = false; + beyondImage = false; + if (savedPosition) + genomePos.set(savedPosition); + var oldPos = prevX.toString() + "px"; + $(".panImg").css( {'left': oldPos }); + $('.tdData').css( {'backgroundPosition': oldPos } ); + if (highlightAreas) + imageV2.drawHighlights(); + return true; + } + + // Do we need to fetch anything? + if (beyondImage) { + if (imageV2.inPlaceUpdate) { + var pos = parsePosition(genomePos.get()); + imageV2.navigateInPlace("db=" + getDb() + "&position=" + encodeURIComponent(pos.chrom + ":" + pos.start + "-" + pos.end), null, true); - } else { - document.TrackHeaderForm.submit(); - } - return true; // Make sure the setTimeout below is not called. + } else { + document.TrackHeaderForm.submit(); } + return true; // Make sure the setTimeout below is not called. + } - // Just a normal scroll within a >1X image - if (prevX !== newX) { - prevX = newX; - if (!only1xScrolling) { - //panAdjustHeight(newX); // Will resize image AFTER scrolling. - // Important, since AJAX could lead to reinit after this within bounds scroll - hgTracks.imgBoxPortalOffsetX = (prevX * -1) - hgTracks.imgBoxLeftLabel; - hgTracks.imgBoxPortalLeft = newX.toString() + "px"; - } + // Just a normal scroll within a >1X image + if (prevX !== newX) { + prevX = newX; + if (!only1xScrolling) { + //panAdjustHeight(newX); // Will resize image AFTER scrolling. + // Important, since AJAX could lead to reinit after this within bounds scroll + hgTracks.imgBoxPortalOffsetX = (prevX * -1) - hgTracks.imgBoxLeftLabel; + hgTracks.imgBoxPortalLeft = newX.toString() + "px"; } } } + } }); // end of this.each(function(){ function panUpdatePosition(newOffsetX,bounded) @@ -1944,16 +1944,16 @@ jQuery.fn.panImages = function () { // Updates the 'position/search" display with change due to panning var closedPortalStart = hgTracks.imgBoxPortalStart + 1; // Correction for half open var portalWidthBases = hgTracks.imgBoxPortalEnd - closedPortalStart; - var portalScrolledX = hgTracks.imgBoxPortalOffsetX + hgTracks.imgBoxLeftLabel + newOffsetX; + var portalScrolledX = hgTracks.imgBoxPortalOffsetX+hgTracks.imgBoxLeftLabel + newOffsetX; var recalculate = false; var newPortalStart = 0; if (hgTracks.revCmplDisp) newPortalStart = closedPortalStart + // As offset goes down, so do bases seen. - Math.round(portalScrolledX * hgTracks.imgBoxBasesPerPixel); + Math.round(portalScrolledX*hgTracks.imgBoxBasesPerPixel); else newPortalStart = closedPortalStart - // As offset goes down, bases seen goes up! - Math.round(portalScrolledX * hgTracks.imgBoxBasesPerPixel); + Math.round(portalScrolledX*hgTracks.imgBoxBasesPerPixel); if (newPortalStart < hgTracks.chromStart && bounded) { // Stay within bounds newPortalStart = hgTracks.chromStart; recalculate = true; @@ -1968,16 +1968,17 @@ jQuery.fn.panImages = function () { var newPos = hgTracks.chromName + ":" + newPortalStart + "-" + newPortalEnd; genomePos.set(newPos); // no need to change the size } - if (recalculate && hgTracks.imgBoxBasesPerPixel > 0) { + if (recalculate && hgTracks.imgBoxBasesPerPixel > 0) { // Need to recalculate X for bounding drag portalScrolledX = (closedPortalStart - newPortalStart) / hgTracks.imgBoxBasesPerPixel; - newOffsetX = portalScrolledX - (hgTracks.imgBoxPortalOffsetX + hgTracks.imgBoxLeftLabel); + newOffsetX = portalScrolledX - (hgTracks.imgBoxPortalOffsetX+hgTracks.imgBoxLeftLabel); } if (typeof (igv) !== "undefined") { - igv.updateIgvStartPosition(newPortalStart); + igv.updateIgvStartPosition(newPortalStart); } + ret = {}; ret.newX = newOffsetX; ret.isOutsideChrom = recalculate; @@ -1985,24 +1986,24 @@ jQuery.fn.panImages = function () { } function mapTopAndBottom(mapName,east,west) { - // Find the top and bottom px given left and right boundaries - var mapPortal = {top: -10, bottom: -10}; - var items = $("map[name='" + mapName + "']").children(); - if ($(items).length > 0) { - $(items).each(function (t) { + // Find the top and bottom px given left and right boundaries + var mapPortal = { top: -10, bottom: -10 }; + var items = $("map[name='"+mapName+"']").children(); + if ($(items).length>0) { + $(items).each(function(t) { var loc = this.coords.split(","); - var aleft = parseInt(loc[0]); - var aright = parseInt(loc[2]); + var aleft = parseInt(loc[0]); + var aright = parseInt(loc[2]); if (aleft < west && aright >= east) { - var atop = parseInt(loc[1]); + var atop = parseInt(loc[1]); var abottom = parseInt(loc[3]); - if (mapPortal.top < 0) { - mapPortal.top = atop; + if (mapPortal.top < 0 ) { + mapPortal.top = atop; mapPortal.bottom = abottom; } else if (mapPortal.top > atop) { - mapPortal.top = atop; + mapPortal.top = atop; } else if (mapPortal.bottom < abottom) { - mapPortal.bottom = abottom; + mapPortal.bottom = abottom; } } }); @@ -2019,42 +2020,42 @@ jQuery.fn.panImages = function () { var east = newOffsetX * -1; var west = east + portalWidth; - $(".panImg").each(function (t) { - var mapid = this.id.replace('img_', 'map_'); - var hDiv = $(this).parent(); - var north = parseInt($(this).css("top")) * -1; - var south = north + $(hDiv).height(); + $(".panImg").each(function(t) { + var mapid = this.id.replace('img_','map_'); + var hDiv = $(this).parent(); + var north = parseInt($(this).css("top")) * -1; + var south = north + $(hDiv).height(); - var mapPortal = mapTopAndBottom(mapid, east, west); + var mapPortal = mapTopAndBottom(mapid,east,west); if (mapPortal.top > 0) { var topdif = Math.abs(mapPortal.top - north); var botdif = Math.abs(mapPortal.bottom - south); if (topdif > 2 || botdif > 2) { - $(hDiv).height(mapPortal.bottom - mapPortal.top); + $(hDiv).height( mapPortal.bottom - mapPortal.top ); north = mapPortal.top * -1; - $(this).css({'top': north.toString() + "px"}); + $(this).css( {'top': north.toString() + "px" }); // Need to adjust side label height as well! var imgId = this.id.split("_"); var titlePx = 0; - var center = $("#img_center_" + imgId[2]); + var center = $("#img_center_"+imgId[2]); if (center.length > 0) { titlePx = $(center).parent().height(); north += titlePx; } - var side = $("#img_side_" + imgId[2]); + var side = $("#img_side_"+imgId[2]); if (side.length > 0) { - $(side).parent().height(mapPortal.bottom - mapPortal.top + titlePx); - $(side).css({'top': north.toString() + "px"}); + $(side).parent().height( mapPortal.bottom - mapPortal.top + titlePx); + $(side).css( {'top': north.toString() + "px" }); } - var btn = $("#p_btn_" + imgId[2]); + var btn = $("#p_btn_"+imgId[2]); if (btn.length > 0) { - $(btn).height(mapPortal.bottom - mapPortal.top + titlePx); + $(btn).height( mapPortal.bottom - mapPortal.top + titlePx); } else { - btn = $("#img_btn_" + imgId[2]); + btn = $("#img_btn_"+imgId[2]); if (btn.length > 0) { - $(btn).parent().height(mapPortal.bottom - mapPortal.top + titlePx); - $(btn).css({'top': top.toString() + "px"}); + $(btn).parent().height( mapPortal.bottom - mapPortal.top + titlePx); + $(btn).css( {'top': top.toString() + "px" }); } } } @@ -2063,7 +2064,7 @@ jQuery.fn.panImages = function () { dragMaskResize(); // Resizes the dragMask to match current image size } - function dragMaskShow() + function dragMaskShow() { // Sets up the dragMask to show grabbing cursor within image // and not allowed north and south of image var imgTbl = $('#imgTbl'); @@ -2074,45 +2075,45 @@ jQuery.fn.panImages = function () { dragMask = $('div#dragMask'); } - $('body').css('cursor', 'not-allowed'); - $(dragMask).css('cursor', "url(../images/grabbing.cur),w-resize"); + $('body').css('cursor','not-allowed'); + $(dragMask).css('cursor',"url(../images/grabbing.cur),w-resize"); $(dragMask).css({opacity:0.0,display:'block', - top: $(imgTbl).position().top.toString() + 'px', - height: $(imgTbl).height().toString() + 'px' }); + top: $(imgTbl).position().top.toString() + 'px', + height: $(imgTbl).height().toString() + 'px' }); } - function dragMaskResize() + function dragMaskResize() { // Resizes dragMask (called when image is dynamically resized in >1x scrolling) var imgTbl = $('#imgTbl'); // Find or create the waitMask (which masks the whole page) var dragMask = normed($('div#dragMask')); if (dragMask) { - $(dragMask).height($(imgTbl).height()); + $(dragMask).height( $(imgTbl).height() ); } } function dragMaskClear() { // Clears the dragMask - $('body').css('cursor', 'auto'); - var dragMask = normed($('#dragMask')); + $('body').css('cursor','auto'); + var dragMask = normed($('#dragMask')); if (dragMask) $(dragMask).hide(); } - function scrollHighlight(relativeX) + function scrollHighlight(relativeX) // Scrolls the highlight region if one exists - { + { if (highlightAreas) { - for (i = 0; i < highlightAreas.length; i++) { + for (i=0; i
    " + - msg + "
    "); - $('#myPromptText').on('keypress', function (e) { + msg + ""); + $('#myPromptText').on('keypress', function(e) { if (e.which === 13) { // listens for return key e.preventDefault(); // prevents return from also submitting whole form $("#myPrompt").dialog("close"); @@ -2315,22 +2316,22 @@ var rightClick = { } }); $("#myPrompt").dialog({ - modal: true, - closeOnEscape: true, - buttons: { "OK": function() { - var myPromptText = $("#myPromptText").val(); - $(this).dialog("close"); - callback(myPromptText); - } - } - }); + 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); + setTimeout( function() { + rightClick.hitFinish(menuItemClicked, menuObject, cmd, args); + }, 1); }, hitFinish: function (menuItemClicked, menuObject, cmd, args) @@ -2342,126 +2343,126 @@ var rightClick = { var row = null; var rows = null; var selectUpdated = null; - function mySuccess() {} + function mySuccess() {} 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)); + // 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)); + 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, true); - } + if (result.chromStart != -1) + { + var newPos2 = hgTracks.chromName+":"+(result.chromStart+1)+"-"+result.chromEnd; + dragSelect.highlightThisRegion(newPos2, true); + } - } else { - var newChrom = hgTracks.chromName; - if (hgTracks.windows && hgTracks.virtualSingleChrom) { - newChrom = hgTracks.windows[0].chromName; + } 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, true); } - var newPos3 = newChrom + ":" + (parseInt(chromStart)) + "-" + parseInt(chromEnd); - dragSelect.highlightThisRegion(newPos3, true); - } - } 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); + 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() + "&db=" + getDb(); + 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) + // Add or update form input with gene to highlight + suggestBox.updateFindMatches(name); + ele.submit(); } - } - 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() + "&db=" + getDb(); - 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) - // Add or update form input with gene to highlight - suggestBox.updateFindMatches(name); - ele.submit(); } } - } } else if (cmd === 'zoomCodon' || cmd === 'zoomExon') { var num, ajaxCmd, msg; if (cmd === 'zoomCodon') { @@ -2471,27 +2472,27 @@ var rightClick = { msg = "Please enter the exon number to zoom to:"; ajaxCmd = 'exonToPos'; } - rightClick.myPrompt(msg, function (results) { + rightClick.myPrompt(msg, function(results) { $.ajax({ - type: "GET", - url: "../cgi-bin/hgApi", - data: cart.varsToUrlData({ 'hgsid': getHgsid(), 'db': getDb(), 'cmd': ajaxCmd, 'num': results, - 'table': args.table, 'name': args.name, 'chrom': hgTracks.chromName}), - trueSuccess: rightClick.handleZoomCodon, - success: catchErrorOrDispatch, - error: errorHandler, - cache: true - }); - }); + type: "GET", + url: "../cgi-bin/hgApi", + data: cart.varsToUrlData({ 'hgsid': getHgsid(), 'db': getDb(), 'cmd': ajaxCmd, 'num': results, + 'table': args.table, 'name': args.name, 'chrom': hgTracks.chromName}), + 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); + popUp.hgTrackUi( rightClick.selectedMenuItem.id, false ); } else if (cmd === 'hgTrackUi_popup_description') { // Launches the popup but shields the ajax with a waitOnFunction - popUp.hgTrackUi(rightClick.selectedMenuItem.id, true); + popUp.hgTrackUi( rightClick.selectedMenuItem.id, true ); } else if (cmd === 'hgTrackUi_follow') { @@ -2501,7 +2502,7 @@ var rightClick = { url += rec.parentTrack; else { // The button already has the ref - var link = normed($('td#td_btn_' + rightClick.selectedMenuItem.id).children('a')); + var link = normed($( 'td#td_btn_'+ rightClick.selectedMenuItem.id ).children('a')); if (link) url = $(link).attr('href'); else @@ -2514,7 +2515,7 @@ var rightClick = { type: "PUT", async: false, url: "../cgi-bin/hgCollection", - data: "cmd=newCollection&track=" + id + "&hgsid=" + getHgsid(), + data: "cmd=newCollection&track=" + id + "&hgsid=" + getHgsid(), trueSuccess: mySuccess, success: catchErrorOrDispatch, error: errorHandler, @@ -2522,11 +2523,11 @@ var rightClick = { imageV2.fullReload(); } else if (cmd === 'addCollection') { - var shortLabel = $(menuItemClicked).text().substring(9).slice(0, -1); + var shortLabel = $(menuItemClicked).text().substring(9).slice(0,-1); var ii; var collectionName; - for (ii = 0; ii < hgTracks.collections.length; ii++) { - if (hgTracks.collections[ii].shortLabel === shortLabel) { + for(ii=0; ii < hgTracks.collections.length; ii++) { + if ( hgTracks.collections[ii].shortLabel === shortLabel) { collectionName = hgTracks.collections[ii].track; break; } @@ -2556,7 +2557,7 @@ var rightClick = { url += rec.parentTrack; else { // The button already has the ref - var link2 = normed($('td#td_btn_' + rightClick.selectedMenuItem.id).children('a')); + var link2 = normed($( 'td#td_btn_'+ rightClick.selectedMenuItem.id ).children('a')); if (link2) url = $(link2).attr('href'); else @@ -2569,17 +2570,17 @@ var rightClick = { // 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(), 'db': getDb() }), - dataType: "html", - trueSuccess: rightClick.handleViewImg, - success: catchErrorOrDispatch, - error: errorHandler, - cmd: cmd, - cache: false - }); + type: "GET", + url: "../cgi-bin/hgTracks", + data: cart.varsToUrlData({ 'hgt.imageV1': '1','hgt.trackImgOnly': '1', + 'hgsid': getHgsid(), 'db': getDb() }), + 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"); @@ -2596,9 +2597,9 @@ var rightClick = { val = hgTracks[valNames[i]]; } if (val - && id !== "wikiTrack" - && (href.indexOf("?" + v + "=") === -1) - && (href.indexOf("&" + v + "=") === -1)) { + && id !== "wikiTrack" + && (href.indexOf("?" + v + "=") === -1) + && (href.indexOf("&" + v + "=") === -1)) { href = href + "&" + v + "=" + val; } } @@ -2607,7 +2608,7 @@ var rightClick = { } else { // XXXX This is blocked by Safari's popup blocker (without any warning message). href = removeHgsid(href); - if (!window.open(href)) { + if ( ! window.open(href) ) { rightClick.windowOpenFailedMsg(); } } @@ -2627,16 +2628,16 @@ var rightClick = { imageV2.requestImgUpdate(id, "hgt.transparentImage=0", ""); } } else if (cmd === 'hideSet') { - row = $('tr#tr_' + id); + 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--) { + 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; + varsToUpdate[rowId] = '[]'; + varsToUpdate[rowId+'_sel'] = 0; $(rows[ix]).remove(); } if (objNotEmpty(varsToUpdate)) { @@ -2647,33 +2648,33 @@ var rightClick = { } else if (cmd === 'hideComposite') { rec = hgTracks.trackDb[id]; if (tdbIsSubtrack(rec)) { - let trid = id.replaceAll(".", "\\."); - row = $('tr#tr_' + trid); + let trid = id.replaceAll(".","\\."); + row = $( 'tr#tr_' + trid ); 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--) { + 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); + 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 && rightClick.clickedHighlightIdx !== null) { + if (hgTracks.highlight && rightClick.clickedHighlightIdx!==null) { var newPos = getHighlight(hgTracks.highlight, rightClick.clickedHighlightIdx); if (newPos && newPos.db === getDb()) { - if ($('#highlightItem').length === 0) { // not visible? jump to it + 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); + newPos.start = Math.max( Math.floor(newPos.start - (diff/2) ), 0 ); + newPos.end = newPos.start + (curPos.end - curPos.start); } } if (imageV2.inPlaceUpdate) { - var params = "db=" + getDb() + "&position=" + newPos.chrom + ':' + newPos.start + '-' + newPos.end; + var params = "db=" + getDb() + "&position=" + newPos.chrom+':'+newPos.start+'-'+newPos.end; imageV2.navigateInPlace(params, null, true); } else { genomePos.setByCoordinates(newPos.chrom, newPos.start, newPos.end); @@ -2688,7 +2689,7 @@ var rightClick = { var highlights = hgTracks.highlight.split("|"); highlights.splice(rightClick.clickedHighlightIdx, 1); // splice = remove element from array hgTracks.highlight = highlights.join("|"); - cart.setVarsObj({'highlight': hgTracks.highlight}); + cart.setVarsObj({'highlight' : hgTracks.highlight}); imageV2.drawHighlights(); } else if (cmd === 'toggleMerge') { // toggle both the cart (if the user goes to trackUi) @@ -2698,12 +2699,12 @@ var rightClick = { if (args[key] === 1) { args[key] = 0; updateObj[key] = 0; - cart.setVarsObj(updateObj, null, false); + cart.setVarsObj(updateObj,null,false); imageV2.requestImgUpdate(id, id + ".doMergeItems=0"); } else { args[key] = 1; updateObj[key] = 1; - cart.setVarsObj(updateObj, null, false); + cart.setVarsObj(updateObj,null,false); imageV2.requestImgUpdate(id, id + ".doMergeItems=1"); } } else { // if ( cmd in 'hide','dense','squish','pack','full','show' ) @@ -2724,9 +2725,9 @@ var rightClick = { // assert(document.TrackForm); document.TrackForm.submit(); } else { - // Add vis update to queue then submit - cart.setVars([id], [cmd], null, false); // synchronous - document.TrackHeaderForm.submit(); + // Add vis update to queue then submit + cart.setVars([id], [cmd], null, false); // synchronous + document.TrackHeaderForm.submit(); } } else { imageV2.requestImgUpdate(id, id + "=" + cmd, "", cmd); @@ -2736,7 +2737,7 @@ var rightClick = { makeHitCallback: function (title) { // stub to avoid problem with a function closure w/n a loop - return function (menuItemClicked, menuObject) { + return function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked, menuObject, title); return true; }; }, @@ -2745,7 +2746,7 @@ var rightClick = { { // currently dead (experimental code) if (rightClick.floatingMenuItem) { $('#img_data_' + rightClick.floatingMenuItem).parent().makeFloat( - {x: "current", y: "current", speed: 'fast', alwaysVisible: true, alwaysTop: true}); + {x:"current",y:"current", speed: 'fast', alwaysVisible: true, alwaysTop: true}); } }, @@ -2755,7 +2756,7 @@ var rightClick = { // seen in FireFox 3.X, which occurred b/c FF doesn't actually fetch the image until // the menu is being shown. return ""; + img + "' />"; }, @@ -2783,572 +2784,572 @@ var rightClick = { 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; - let trid = id.replaceAll(".", "\\."); - var row = $('tr#tr_' + trid); - 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 - } + 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; + let trid = id.replaceAll(".","\\."); + var row = $( 'tr#tr_' + trid ); + 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); - } - + // First option is hide sets + if (offerHideComposite) { + if (offerHideSubset) { o = {}; - str = blankImg + " hide track set"; - if (offerHideSubset) - str += " (blue)"; - o[str] = {onclick: rightClick.makeHitCallback('hideComposite')}; + o[blankImg + " hide track subset (green)"] = { + onclick: rightClick.makeHitCallback('hideSet')}; 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) { + 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]) { + 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]; } - o[str] = { onclick: - rightClick.makeHitCallback(visStrings[i]) - }; - menu.push(o); + } else if (visStrings[i] === vis.enumOrder[rec.visibility]) { + str = selectedImg + " " + visStrings[i]; } + o[str] = { onclick: + rightClick.makeHitCallback(visStrings[i]) + }; + menu.push(o); } - done = true; } + done = true; } } + } - if (done) { - o = {}; - var any = false; - var title = rightClick.selectedMenuItem.title || "feature"; - var maxLength = 60; - - if ((isGene || isHgc || id === "wikiTrack") && href.indexOf("i=mergedItem") === -1) { - // 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; - } - // For barChart mouseovers, replace title (which may be a category - // name+value) with item name - if (rec.type.indexOf("barChart") === 0 - || rec.type.indexOf("bigBarChart") === 0) { - let a = /i=([^&]+)/.exec(href); - if (a && a[1]) { - title = a[1]; - } + if (done) { + o = {}; + var any = false; + var title = rightClick.selectedMenuItem.title || "feature"; + var maxLength = 60; + + if ((isGene || isHgc || id === "wikiTrack") && href.indexOf("i=mergedItem") === -1) { + // 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; + } + // For barChart mouseovers, replace title (which may be a category + // name+value) with item name + if (rec.type.indexOf("barChart") === 0 + || rec.type.indexOf("bigBarChart") === 0) { + let a = /i=([^&]+)/.exec(href); + if (a && a[1]) { + title = a[1]; } } + } - // pick out the exon number from the mouseover text - // Probably should be a data-exonNum tag on the DOM element - var exonNum = rightClick.mouseOverToExon(title); + // pick out the exon number from the mouseover text + // Probably should be a data-exonNum tag on the DOM element + var exonNum = rightClick.mouseOverToExon(title); - // remove special genePred exon mouseover html text - // CGIs now use HTML tags, e.g. "Transcript: ENST00000297261.7
    Strand:" - title = rightClick.mouseOverToLabel(title); + // remove special genePred exon mouseover html text + // CGIs now use HTML tags, e.g. "Transcript: ENST00000297261.7
    Strand:" + title = rightClick.mouseOverToLabel(title); - if (title.length > maxLength) { - title = title.substring(0, maxLength) + "..."; - } + if (title.length > maxLength) { + title = title.substring(0, maxLength) + "..."; + } - if (isHgc && (href.indexOf('g=gtexGene') !== -1 - || href.indexOf('g=unip') !== -1 - || href.indexOf('g=knownGene') !== -1)) { - // For GTEx gene and UniProt mouseovers, replace title (which may be a tissue name) with - // item (gene) name. Also need to unescape the urlencoded characters and the + sign. - let a = /i=([^&]+)/.exec(href); - if (a && a[1]) { - title = decodeURIComponent(a[1].replace(/\+/g, " ")); - } + if (isHgc && ( href.indexOf('g=gtexGene')!== -1 + || href.indexOf('g=unip') !== -1 + || href.indexOf('g=knownGene') !== -1 )) { + // For GTEx gene and UniProt mouseovers, replace title (which may be a tissue name) with + // item (gene) name. Also need to unescape the urlencoded characters and the + sign. + let a = /i=([^&]+)/.exec(href); + if (a && a[1]) { + title = decodeURIComponent(a[1].replace(/\+/g, " ")); } + } - if (displayItemFunctions) { - o[rightClick.makeImgTag("magnify.png") + " Zoom to " + title] = { - onclick: function (menuItemClicked, menuObject) { + 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, - "selectWholeGene"); return true; + "highlightItem"); + return true; } }; - o[rightClick.makeImgTag("highlight.png") + " Highlight " + title] = - { onclick: function(menuItemClicked, menuObject) { - rightClick.hit(menuItemClicked, menuObject, - "highlightItem"); - return true; - } - }; - if (rightClick.supportZoomCodon && + if (rightClick.supportZoomCodon && (rec.type.indexOf("genePred") !== -1 || rec.type.indexOf("bigGenePred") !== -1)) { - // http://hgwdev-larrym.gi.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=([^&]+)"); - let a = reg.exec(href); + // http://hgwdev-larrym.gi.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=([^&]+)"); + let 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.gi.ucsc.edu/cgi-bin/hgc?o=55086724&t=55275031&g=refGene&i=NM_005228&c=chr7 + // http://hgwdev-larrym.gi.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("hgg_type=([^&]+)"); + reg = new RegExp("g=([^&]+)"); a = reg.exec(href); if (a && a[1]) { table = a[1]; } - } else { - // http://hgwdev-larrym.gi.ucsc.edu/cgi-bin/hgc?o=55086724&t=55275031&g=refGene&i=NM_005228&c=chr7 - // http://hgwdev-larrym.gi.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) { - if (exonNum > 0) { - o[rightClick.makeImgTag("magnify.png") + " Zoom to this exon"] = { - onclick: function (menuItemClicked, menuObject) { - $.ajax({ + } + if (name && table) { + if (exonNum > 0) { + o[rightClick.makeImgTag("magnify.png")+" Zoom to this exon"] = { + onclick: function(menuItemClicked, menuObject) { + $.ajax({ type: "GET", url: "../cgi-bin/hgApi", data: cart.varsToUrlData({ 'hgsid': getHgsid(), 'db': getDb(), - 'cmd': "exonToPos", 'num': exonNum, - 'table': table, 'name': name, 'chrom': hgTracks.chromName}), + 'cmd': "exonToPos", 'num': exonNum, + 'table': table, 'name': name, 'chrom': hgTracks.chromName}), trueSuccess: rightClick.handleZoomCodon, success: catchErrorOrDispatch, error: errorHandler, cache: true }); - return true; } - }; - o[rightClick.makeImgTag("magnify.png") + " Enter codon to zoom to..."] = - { onclick: function(menuItemClicked, menuObject) { - rightClick.hit(menuItemClicked, menuObject, - "zoomCodon", - {name: name, table: table, 'chrom': hgTracks.chromName}); - return true;} - }; - o[rightClick.makeImgTag("magnify.png") + " Enter exon to zoom to..."] = - { onclick: function(menuItemClicked, menuObject) { - rightClick.hit(menuItemClicked, menuObject, + return true; } + }; + o[rightClick.makeImgTag("magnify.png")+" Enter codon to zoom to..."] = + { onclick: function(menuItemClicked, menuObject) { + rightClick.hit(menuItemClicked, menuObject, + "zoomCodon", + {name: name, table: table, 'chrom': hgTracks.chromName}); + return true;} + }; + o[rightClick.makeImgTag("magnify.png")+" Enter exon to zoom to..."] = + { onclick: function(menuItemClicked, menuObject) { + rightClick.hit(menuItemClicked, menuObject, "zoomExon", {name: name, table: table, 'chrom': hgTracks.chromName}); - return true;} - }; - } + 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"); + o[rightClick.makeImgTag("dnaIcon.png")+" Get DNA for "+title] = { + onclick: function(menuItemClicked, menuObject) { + rightClick.hit(menuItemClicked, menuObject, "getDna"); return true; } }; - any = true; } - if (href && href.length > 0 && href.indexOf("i=mergedItem") === -1) { - // 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); + 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 && href.indexOf("i=mergedItem") === -1) { + // 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); + } } + } - menu.push($.contextMenu.separator); - o = {}; - o[rightClick.makeImgTag("hiddenIcon.png") + " Hide all other tracks "] = { - onclick: function (menuItemClicked, menuObject) { - rightClick.hit(menuItemClicked, menuObject, "hideOthers"); - return true; } - }; - menu.push(o); + menu.push($.contextMenu.separator); + o = {}; + o[rightClick.makeImgTag("hiddenIcon.png") + " Hide all other tracks "] = { + onclick: function(menuItemClicked, menuObject) { + rightClick.hit(menuItemClicked, menuObject, "hideOthers"); + return true; } + }; + menu.push(o); - //o = {}; - //o[" Float "] = { + //o = {}; + //o[" Float "] = { //onclick: function(menuItemClicked, menuObject) { - //rightClick.hit(menuItemClicked, menuObject, "float"); - //return true; } - //}; - //menu.push(o); - - o = {}; - o[rightClick.makeImgTag("ab_up.gif") + " Move to top "] = { - onclick: function (menuItemClicked, menuObject) { - rightClick.hit(menuItemClicked, menuObject, "moveTop"); - return true; } - }; - menu.push(o); - - o = {}; - o[rightClick.makeImgTag("ab_down.gif") + " Move to bottom "] = { - onclick: function (menuItemClicked, menuObject) { - rightClick.hit(menuItemClicked, menuObject, "moveBottom"); - return true; } - }; - 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"); + //rightClick.hit(menuItemClicked, menuObject, "float"); + //return true; } + //}; + //menu.push(o); + + o = {}; + o[rightClick.makeImgTag("ab_up.gif") + " Move to top "] = { + onclick: function(menuItemClicked, menuObject) { + rightClick.hit(menuItemClicked, menuObject, "moveTop"); + return true; } + }; + menu.push(o); + + o = {}; + o[rightClick.makeImgTag("ab_down.gif") + " Move to bottom "] = { + onclick: function(menuItemClicked, menuObject) { + rightClick.hit(menuItemClicked, menuObject, "moveBottom"); + return true; } + }; + 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; } }; + } - // add a toggle to hide/show the merged item(s) - mergeTrack = rightClick.selectedMenuItem.id + ".doMergeItems"; - if (rec.hasOwnProperty(mergeTrack)) { - var hasMergedItems = rec[mergeTrack] === 1; - titleStr = rightClick.makeImgTag("wrench.png") + " "; - if (hasMergedItems) { - titleStr += "Show merged items"; - } else { - titleStr += "Merge items that span the current region"; - } - o[titleStr] = {onclick: function(menuItemClick, menuObject) { - rightClick.hit(menuItemClick, menuObject, "toggleMerge", rec); + 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("book.png") + " Track Description " + rec.shortLabel] = { - onclick: function (menuItemClicked, menuObject) { - rightClick.hit(menuItemClicked, menuObject, "hgTrackUi_popup_description"); + 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); + } + // add a toggle to hide/show the merged item(s) + mergeTrack = rightClick.selectedMenuItem.id + ".doMergeItems"; + if (rec.hasOwnProperty(mergeTrack)) { + var hasMergedItems = rec[mergeTrack] === 1; + titleStr = rightClick.makeImgTag("wrench.png") + " "; + if (hasMergedItems) { + titleStr += "Show merged items"; + } else { + titleStr += "Merge items that span the current region"; + } + o[titleStr] = {onclick: function(menuItemClick, menuObject) { + rightClick.hit(menuItemClick, menuObject, "toggleMerge", rec); + return true; } + }; } + o[rightClick.makeImgTag("book.png")+" Track Description "+rec.shortLabel] = { + onclick: function(menuItemClicked, menuObject) { + rightClick.hit(menuItemClicked, menuObject, "hgTrackUi_popup_description"); + return true; } + }; + menu.push($.contextMenu.separator); - if (hgTracks.highlight && rightClick.clickedHighlightIdx !== null) { - var currentlySeen = ($('#highlightItem').length > 0); - o = {}; - // Jumps to highlight when not currently seen in image - var text = (currentlySeen ? " Zoom" : " Jump") + " to highlight"; - o[rightClick.makeImgTag("highlightZoom.png") + text] = { - onclick: rightClick.makeHitCallback('jumpToHighlight') - }; + menu.push(o); + } - if (currentlySeen) { // Remove only when seen - o[rightClick.makeImgTag("highlightRemove.png") + - " Remove highlight"] = { - onclick: rightClick.makeHitCallback('removeHighlight') - }; - } - menu.push(o); + menu.push($.contextMenu.separator); + if (hgTracks.highlight && rightClick.clickedHighlightIdx!==null) { + var currentlySeen = ($('#highlightItem').length > 0); + o = {}; + // Jumps to highlight when not currently seen in image + var text = (currentlySeen ? " Zoom" : " Jump") + " to highlight"; + o[rightClick.makeImgTag("highlightZoom.png") + text] = { + onclick: rightClick.makeHitCallback('jumpToHighlight') + }; + + if ( currentlySeen ) { // Remove only when seen + o[rightClick.makeImgTag("highlightRemove.png") + + " Remove highlight"] = { + onclick: rightClick.makeHitCallback('removeHighlight') + }; } + menu.push(o); + } - if (rec.isCustomComposite) + if (rec.isCustomComposite) { - // add delete from composite + // add delete from composite } - else if ((!rec.type.startsWith("wigMaf")) && - (rec.type.startsWith("bigWig") || rec.type.startsWith("multiWig") || rec.type.startsWith("wig") || rec.type.startsWith("bedGraph"))) { - o = {}; - o[" Make a New Collection with \"" + rec.shortLabel + "\""] = { - onclick: rightClick.makeHitCallback("newCollection") - }; - menu.push(o); + else if ((!rec.type.startsWith("wigMaf")) && + (rec.type.startsWith("bigWig") || rec.type.startsWith("multiWig") || rec.type.startsWith("wig") || rec.type.startsWith("bedGraph"))) { + o = {}; + o[" Make a New Collection with \"" + rec.shortLabel + "\""] = { + onclick: rightClick.makeHitCallback("newCollection") + }; + menu.push(o); - if (hgTracks.collections) { - var ii; - for (ii = 0; ii < hgTracks.collections.length; ii++) { - o = {}; - o[" Add to \"" + hgTracks.collections[ii].shortLabel + "\""] = { - onclick: rightClick.makeHitCallback("addCollection") - }; - menu.push(o); - } + if (hgTracks.collections) { + var ii; + for(ii=0; ii < hgTracks.collections.length; ii++) { + o = {}; + o[" Add to \"" + hgTracks.collections[ii].shortLabel + "\""] = { + onclick: rightClick.makeHitCallback("addCollection") + }; + menu.push(o); } - menu.push($.contextMenu.separator); } + menu.push($.contextMenu.separator); + } - // add sort options if this is a custom composite - if (rec.isCustomComposite && tdbHasParent(rec) && tdbIsLeaf(rec)) { - - o = {}; - o[" Sort by Magnitude "] = { - onclick: function (menuItemClicked, menuObject) { - rightClick.hit(menuItemClicked, menuObject, "sortExp"); - return true; } - }; - menu.push(o); - - o = {}; - o[" Sort by Similarity "] = { - onclick: function (menuItemClicked, menuObject) { - rightClick.hit(menuItemClicked, menuObject, "sortSim"); - return true; } - }; - menu.push(o); + // add sort options if this is a custom composite + if (rec.isCustomComposite && tdbHasParent(rec) && tdbIsLeaf(rec)) { - menu.push($.contextMenu.separator); - } + o = {}; + o[" Sort by Magnitude "] = { + onclick: function(menuItemClicked, menuObject) { + rightClick.hit(menuItemClicked, menuObject, "sortExp"); + return true; } + }; + 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"); + o[" Sort by Similarity "] = { + onclick: function(menuItemClicked, menuObject) { + rightClick.hit(menuItemClicked, menuObject, "sortSim"); return true; } - }; + }; menu.push(o); - return menu; + menu.push($.contextMenu.separator); + } + + // 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); + + // find the highlight that was clicked + var imageX = (imageV2.imgTbl[0].getBoundingClientRect().left) + imageV2.LEFTADD; + var xDiff = (e.clientX) - imageX; + var clickPos = genomePos.pixelsToBases(img, xDiff, xDiff+1, hgTracks.winStart, hgTracks.winEnd, false); + rightClick.clickedHighlightIdx = dragSelect.findHighlightIdxForPos(clickPos); + + // XXXX? posting.blockUseMap = true; + return true; }, - { - beforeShow: function (e) { - // console.log(mapItems[rightClick.selectedMenuItem]); - rightClick.selectedMenuItem = rightClick.findMapItem(e); - - // find the highlight that was clicked - var imageX = (imageV2.imgTbl[0].getBoundingClientRect().left) + imageV2.LEFTADD; - var xDiff = (e.clientX) - imageX; - var clickPos = genomePos.pixelsToBases(img, xDiff, xDiff + 1, hgTracks.winStart, hgTracks.winEnd, false); - rightClick.clickedHighlightIdx = dragSelect.findHighlightIdxForPos(clickPos); - - // 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'); - } - }); + 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 //// + ////////////////////////////////// + //// 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