cdaf6a67926c916a57bb8bdd196e5ffc999f159d larrym Thu Jul 28 21:48:14 2011 -0700 switch to using in-memory json; refactor trackDbJson so it is part of hgTracks global in the client (redmine #4550) diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js index a83dc38..7312e0e 100644 --- src/hg/js/hgTracks.js +++ src/hg/js/hgTracks.js @@ -841,31 +841,31 @@ if( btn.length == 0) break; classList = $( btn ).attr("class").split(" "); if (classList[0] != matchClass) break; endIndex = ix; } return rows.slice(startIndex,endIndex+1); // endIndex is 1 based! } function imgTblCompositeSet(row) { // Returns the set of rows that are of the same class and contiguous if(row == null) return null; var rowId = $(row).attr('id').substring('tr_'.length); - var rec = trackDbJson[rowId]; + var rec = hgTracks.trackDb[rowId]; if (tdbIsSubtrack(rec) == false) return null; var rows = $('tr.trDraggable:has(p.' + rec.parentTrack+')'); return rows; } function imgTblZipButtons(table) { // Goes through the image and binds composite track buttons when adjacent var rows = $(table).find('tr'); var lastClass=""; var lastBtn; var lastMatchesLast=false; var lastBlue=true; @@ -1469,61 +1469,61 @@ }, select: function(event, ui) { findTracksSwitchTabs(ui); } }); $('#tabs').show(); $("#tabs").tabs('option', 'selected', '#' + val); if(val =='simpleTab' && $('div#found').length < 1) { $('input#simpleSearch').focus(); } $("#tabs").css('font-family', jQuery('body').css('font-family')); $("#tabs").css('font-size', jQuery('body').css('font-size')); $('.submitOnEnter').keydown(searchKeydown); findTracksNormalize(); updateMetaDataHelpLinks(0); } - if(typeof(trackDbJson) != "undefined" && trackDbJson != null) { - for (var id in trackDbJson) { - var rec = trackDbJson[id]; + if(typeof(hgTracks.trackDb) != "undefined" && hgTracks.trackDb != null) { + for (var id in hgTracks.trackDb) { + var rec = hgTracks.trackDb[id]; if(rec.type == "remote") { if($("#img_data_" + id).length > 0) { // load the remote track renderer via jsonp var script = document.createElement('script'); // XXXX add current image width var pos = parsePosition(getPosition()); script.setAttribute('src', rec.url + "?track=" + id + "&jsonp=remoteTrackCallback&c=" + pos.chrom + "&s=" + pos.start + "&e=" + pos.end); document.getElementsByTagName('head')[0].appendChild(script); } } } } }); function rulerModeToggle (ele) { autoHideSetting = !ele.checked; var obj = imgAreaSelect.data('imgAreaSelect'); obj.setOptions({autoHide : autoHideSetting}); } function makeMapItem(id) { // Create a dummy mapItem on the fly (for objects that don't have corresponding entry in the map). - if(typeof(trackDbJson) != "undefined" && trackDbJson != null) { + if(typeof(hgTracks.trackDb) != "undefined" && hgTracks.trackDb != null) { var title; - var rec = trackDbJson[id]; + var rec = hgTracks.trackDb[id]; if(rec) { title = rec.shortLabel; } else { title = id; } return {id: id, title: "configure " + title}; } else { return null; } } function mapItemMouseOver(obj) { // Record data for current map area item currentMapItem = makeMapItem(obj.id); @@ -1762,31 +1762,31 @@ url: "../cgi-bin/hgApi", data: "db=" + getDb() + "&cmd=" + ajaxCmd + "&num=" + results + "&table=" + args.table + "&name=" + args.name, trueSuccess: handleZoomCodon, success: catchErrorOrDispatch, error: errorHandler, cache: true }); }); } else if (cmd == 'hgTrackUi_popup') { hgTrackUiPopUp( selectedMenuItem.id, false ); // Launches the popup but shields the ajax with a waitOnFunction } else if (cmd == 'hgTrackUi_follow') { var url = "hgTrackUi?hgsid=" + getHgsid() + "&g="; - var rec = trackDbJson[id]; + var rec = hgTracks.trackDb[id]; if (tdbHasParent(rec) && tdbIsLeaf(rec)) url += rec.parentTrack else { var link = $( 'td#td_btn_'+ selectedMenuItem.id ).children('a'); // The button already has the ref if( $(link) != undefined) url = $(link).attr('href'); else url += selectedMenuItem.id; } location.assign(url); } else if (cmd == 'dragZoomMode') { autoHideSetting = true; var obj = imgAreaSelect.data('imgAreaSelect'); obj.setOptions({autoHide : true, movable: false}); @@ -1844,65 +1844,65 @@ // This does work $.floatMgr.FOArray = new Array(); } floatingMenuItem = id; reloadFloatingItem(); updateTrackImg(id, "hgt.transparentImage=0", ""); } } else if (cmd == 'hideSet') { var row = $( 'tr#tr_' + id ); var rows = imgTblContiguousRowSet(row); if (rows && rows.length > 0) { var vars = new Array(); var vals = new Array(); for (var ix=rows.length - 1; ix >= 0; ix--) { // from bottom, just in case remove screws with us var rowId = $(rows[ix]).attr('id').substring('tr_'.length); - //if (tdbIsSubtrack(trackDbJson[rowId]) == false) + //if (tdbIsSubtrack(hgTracks.trackDb[rowId]) == false) // warn('What went wrong?'); vars.push(rowId, rowId+'_sel'); // Remove subtrack level vis and explicitly uncheck. vals.push('[]', 0); $(rows[ix]).remove(); } if (vars.length > 0) { setCartVars( vars, vals ); initImgTblButtons(); loadImgAreaSelect(false); } } } else if (cmd == 'hideComposite') { - var rec = trackDbJson[id]; + var rec = hgTracks.trackDb[id]; if (tdbIsSubtrack(rec)) { var row = $( 'tr#tr_' + id ); var rows = imgTblCompositeSet(row); if (rows && rows.length > 0) { for (var ix=rows.length - 1; ix >= 0; ix--) { // from bottom, just in case remove screws with us $(rows[ix]).remove(); } var selectUpdated = updateVisibility(rec.parentTrack, 'hide'); setCartVar(rec.parentTrack, 'hide' ); initImgTblButtons(); loadImgAreaSelect(false); } } //else // warn('What went wrong?'); } else { // if( cmd in 'hide','dense','squish','pack','full','show' ) // Change visibility settings: // // First change the select on our form: - var rec = trackDbJson[id]; + var rec = hgTracks.trackDb[id]; var selectUpdated = updateVisibility(id, cmd); // Now change the track image if(imageV2 && cmd == 'hide') { // Hide local display of this track and update server side cart. // Subtracks controlled by 2 settings so del vis and set sel=0. Others, just set vis hide. if(tdbIsSubtrack(rec)) setCartVars( [ id, id+"_sel" ], [ '[]', 0 ] ); // Remove subtrack level vis and explicitly uncheck. else if(tdbIsFolderContent(rec)) setCartVars( [ id, id+"_sel" ], [ 'hide', 0 ] ); // supertrack children need to have _sel set to trigger superttrack reshaping else setCartVar(id, 'hide' ); $('#tr_' + id).remove(); initImgTblButtons(); @@ -1985,31 +1985,31 @@ function() { popUpBoxCleanup(); // Popup box is not getting closed properly so must do it here var menu = []; var selectedImg = makeImgTag("greenChecksm.png"); var blankImg = makeImgTag("invisible16.png"); var done = false; if(selectedMenuItem && selectedMenuItem.id != null) { var href = selectedMenuItem.href; var isHgc, isGene; if(href) { isGene = href.match("hgGene"); isHgc = href.match("hgc"); } var id = selectedMenuItem.id; - var rec = trackDbJson[id]; + var rec = hgTracks.trackDb[id]; var offerHideSubset = false; var offerHideComposite = false; var offerSingles = true; var row = $( 'tr#tr_' + id ); if (row) { var btn = $(row).find('p.btnBlue'); // btnBlue means cursor over left button if (btn.length == 1) { var compositeSet = imgTblCompositeSet(row); if (compositeSet && compositeSet.length > 0) { // There is a composite set offerHideComposite = true; $( compositeSet ).find('p.btn').addClass('blueButtons'); // blue persists var subSet = imgTblContiguousRowSet(row); if (subSet && subSet.length > 1) { offerSingles = false; @@ -2287,61 +2287,61 @@ $('#hgTrackUiDialog').html(""); // clear out html after close to prevent problems caused by duplicate html elements popUpTrackName = ""; //set to defaults popUpTrackDescriptionOnly = false; popSaveAllVars = null; } } function _hgTrackUiPopUp(trackName,descriptionOnly) { // popup cfg dialog popUpTrackName = trackName; var myLink = "../cgi-bin/hgTrackUi?g=" + trackName + "&hgsid=" + getHgsid() + "&db=" + getDb(); popUpTrackDescriptionOnly = descriptionOnly; if(popUpTrackDescriptionOnly) myLink += "&descriptionOnly=1"; - var rec = trackDbJson[trackName]; + var rec = hgTracks.trackDb[trackName]; if(!descriptionOnly && rec != null && rec["configureBy"] != null) { if (rec["configureBy"] == 'none') return; else if (rec["configureBy"] == 'clickThrough') { jQuery('body').css('cursor', 'wait'); window.location = myLink; return; } // default falls through to configureBy popup } myLink += "&ajax=1"; $.ajax({ type: "GET", url: myLink, dataType: "html", trueSuccess: handleTrackUi, success: catchErrorOrDispatch, error: errorHandler, cmd: selectedMenuItem, cache: false }); } function hgTrackUiPopUp(trackName,descriptionOnly) { waitOnFunction( _hgTrackUiPopUp, trackName, descriptionOnly ); // Launches the popup but shields the ajax with a waitOnFunction } function hgTrackUiPopCfgOk(popObj, trackName) { // When hgTrackUi Cfg popup closes with ok, then update cart and refresh parts of page - var rec = trackDbJson[trackName]; + var rec = hgTracks.trackDb[trackName]; var subtrack = tdbIsSubtrack(rec) ? trackName :undefined; // If subtrack then vis rules differ var allVars = getAllVars($('#pop'), subtrack ); var changedVars = varHashChanges(allVars,popSaveAllVars); //warn("cfgVars:"+varHashToQueryString(changedVars)); var newVis = changedVars[trackName]; var hide = (newVis != null && (newVis == 'hide' || newVis == '[]')); // subtracks do not have "hide", thus '[]' if($('#imgTbl') == undefined) { // On findTracks or config page setVarsFromHash(changedVars); //if(hide) // TODO: When findTracks or config page has cfg popup, then vis change needs to be handled in page here } else { // On image page if(hide) { setVarsFromHash(changedVars); $('#tr_' + trackName).remove(); initImgTblButtons(); @@ -2398,31 +2398,31 @@ $(cssFiles).each(function (i) { bix = "<LINK rel='STYLESHEET' href='".length; eix = this.lastIndexOf("' TYPE='text/css' />"); file = this.substring(bix,eix); $.getScript(file); // Should protect against already loaded files. }); */ /* //in open ? Loads fine, but then dialog gets confused $(jsFiles).each(function (i) { bix = "<script type='text/javascript' SRC='".length; eix = this.lastIndexOf("'></script>"); file = this.substring(bix,eix); //$.getScript(file,function(data) { warn(data.substring(0,20) + " loaded")}); });*/ if( ! popUpTrackDescriptionOnly ) { - var subtrack = tdbIsSubtrack(trackDbJson[popUpTrackName]) ? popUpTrackName :""; // If subtrack then vis rules differ + var subtrack = tdbIsSubtrack(hgTracks.trackDb[popUpTrackName]) ? popUpTrackName :""; // If subtrack then vis rules differ popSaveAllVars = getAllVars( $('#hgTrackUiDialog'), subtrack ); // Saves the vars that may get changed by the popup cfg. // -- popup.ready() -- Here is the place to do things that might otherwise go into a $('#pop').ready() routine! if (!newJQuery) { $('#hgTrackUiDialog').find('.filterComp').each( function(i) { // Do this by 'each' to set noneIsAll individually $(this).dropdownchecklist({ firstItemChecksAll: true, noneIsAll: $(this).hasClass('filterBy'), maxDropHeight: filterByMaxHeight(this), emptyText: "Please select ...", textFormatFunction: ddclTextFormatter }); }); } } // Searching for some selblance of size suitability @@ -2442,63 +2442,63 @@ width: popWidth, minHeight: 200, minWidth: 700, maxHeight: popMaxHeight, maxWidth: popMaxWidth, modal: true, closeOnEscape: true, autoOpen: false, buttons: { "OK": function() { if( ! popUpTrackDescriptionOnly ) hgTrackUiPopCfgOk($('#pop'), popUpTrackName); $(this).dialog("close"); }}, // popup.ready() doesn't seem to work in open. So there is no need for open at this time. //open: function() { - // var subtrack = tdbIsSubtrack(trackDbJson[popUpTrackName]) ? popUpTrackName :""; // If subtrack then vis rules differ + // var subtrack = tdbIsSubtrack(hgTracks.trackDb[popUpTrackName]) ? popUpTrackName :""; // If subtrack then vis rules differ // popSaveAllVars = getAllVars( $('#pop'), subtrack ); //}, open: function () { if (newJQuery) { if( ! popUpTrackDescriptionOnly ) { $('#hgTrackUiDialog').find('.filterBy,.filterComp').each( function(i) { if ($(this).hasClass('filterComp')) ddcl.setup(this); else ddcl.setup(this, 'noneIsAll'); }); } } }, close: function() { popUpBoxCleanup(); } }); // FIXME: Why are open and close no longer working!!! if(popUpTrackDescriptionOnly) { var myWidth = $(window).width() - 300; if(myWidth > 900) myWidth = 900; $('#hgTrackUiDialog').dialog("option", "maxWidth", myWidth); $('#hgTrackUiDialog').dialog("option", "width", myWidth); - $('#hgTrackUiDialog').dialog('option' , 'title' , trackDbJson[popUpTrackName].shortLabel + " Track Description"); + $('#hgTrackUiDialog').dialog('option' , 'title' , hgTracks.trackDb[popUpTrackName].shortLabel + " Track Description"); $('#hgTrackUiDialog').dialog('open'); var buttOk = $('button.ui-state-default'); if($(buttOk).length == 1) $(buttOk).focus(); } else { - $('#hgTrackUiDialog').dialog('option' , 'title' , trackDbJson[popUpTrackName].shortLabel + " Track Settings"); + $('#hgTrackUiDialog').dialog('option' , 'title' , hgTracks.trackDb[popUpTrackName].shortLabel + " Track Settings"); $('#hgTrackUiDialog').dialog('open'); } } function afterImgTblReload() { // Reload various UI widgets after updating imgTbl map. parseMap(null, true); $("map[name!=ideoMap]").each( function(t) { parseMap($(this, false));}); initImgTblButtons(); loadImgAreaSelect(false); // Do NOT reload context menu (otherwise we get the "context menu sticks" problem). // loadContextMenu($('#tr_' + id)); if(trackImgTbl.tableDnDUpdate) trackImgTbl.tableDnDUpdate(); @@ -2518,92 +2518,88 @@ //var img = $('#tr_' + id).find("img[id^='img_data_']").attr('src'); //warn("Just parsed image:<BR>"+img); return true; } else { return false; } } function handleUpdateTrackMap(response, status) { // Handle ajax response with an updated trackMap image (gif or png) and map. // // this.cmd can be used to figure out which menu item triggered this. // this.id == appropriate track if we are retrieving just a single track. - // update local trackDbJson to reflect possible side-effects of ajax request. - var json = scrapeVariable(response, "trackDbJson"); - if(json == null) { - showWarning("trackDbJson is missing from the response"); + // update local hgTracks.trackDb to reflect possible side-effects of ajax request. + var json = scrapeVariable(response, "hgTracks"); + if(json == undefined) { + showWarning("hgTracks object is missing from the response"); } else { if(this.id != null) { - if(json[this.id]) { - var visibility = visibilityStrsOrder[json[this.id].visibility]; + if(json.trackDb[this.id]) { + var visibility = visibilityStrsOrder[json.trackDb[this.id].visibility]; var limitedVis; - if(json[this.id].limitedVis) - limitedVis = visibilityStrsOrder[json[this.id].limitedVis]; + if(json.trackDb[this.id].limitedVis) + limitedVis = visibilityStrsOrder[json.trackDb[this.id].limitedVis]; if(this.newVisibility && limitedVis && this.newVisibility != limitedVis) alert("There are too many items to display the track in " + this.newVisibility + " mode."); - var rec = trackDbJson[this.id]; - rec.limitedVis = json[this.id].limitedVis; + var rec = hgTracks.trackDb[this.id]; + rec.limitedVis = json.trackDb[this.id].limitedVis; updateVisibility(this.id, visibility); } else { - showWarning("Invalid trackDbJson received from the server"); + showWarning("Invalid hgTracks.trackDb received from the server"); } } else { - trackDbJson = json; + hgTracks.trackDb = json.trackDb; } } if(this.loadingId) { hideLoadingImage(this.loadingId); } if(imageV2 && this.id && this.cmd && this.cmd != 'wholeImage' && this.cmd != 'selectWholeGene') { // Extract <TR id='tr_ID'>...</TR> and update appropriate row in imgTbl; // this updates src in img_left_ID, img_center_ID and img_data_ID and map in map_data_ID var id = this.id; if(updateTrackImgForId(response, id)) { afterImgTblReload(); } else { showWarning("Couldn't parse out new image for id: " + id); //alert("Couldn't parse out new image for id: " + id+"BR"+response); // Very helpful } } else { if(imageV2) { // Implement in-place updating of hgTracks image // // We update rows one at a time (updating the whole imgTable at one time doesn't work in IE). - for (id in trackDbJson) { + for (id in hgTracks.trackDb) { if(!updateTrackImgForId(response, id)) { showWarning("Couldn't parse out new image for id: " + id); //alert("Couldn't parse out new image for id: " + id+"BR"+response); // Very helpful } } - var json = scrapeVariable(response, "hgTracks"); - if(json != undefined) { + // update hgTracks as appropriate (XXXX should we just copy over the whole thing rather than just specific keys?) hgTracks.chromName = json.chromName; hgTracks.winStart = json.winStart; hgTracks.winEnd = json.winEnd; $("input[name='c']").val(json.chromName); $("input[name='l']").val(json.winStart); $("input[name='r']").val(json.winEnd); hgTracks.newWinWidth = json.newWinWidth; setPositionByCoordinates(hgTracks.chromName, hgTracks.winStart + 1, hgTracks.winEnd); originalPosition = undefined; initVars(); - } else { - showWarning("Couldn't parse out new position info"); - } afterImgTblReload(); } else { a= /<IMG([^>]+SRC[^>]+id='trackMap[^>]*)>/.exec(response); // Deal with a is null if(a[1]) { var b = /WIDTH\s*=\s*['"]?(\d+)['"]?/.exec(a[1]); var width = b[1]; b = /HEIGHT\s*=\s*['"]?(\d+)['"]?/.exec(a[1]); var height = b[1]; b = /SRC\s*=\s*"([^")]+)"/.exec(a[1]); var src = b[1]; $('#trackMap').attr('src', src); var obj = imgAreaSelect.data('imgAreaSelect'); if(width) { trackImg.attr('width', width); @@ -2715,49 +2711,49 @@ // Required to fix problem on IE and Safari where value of hgt_tSearch is "-" (i.e. not "Search"). $("input[name=hgt_tsPage]").val(0); // NOTE: must match TRACK_SEARCH_PAGER in hg/inc/searchTracks.h $('#trackSearch').submit(); // This doesn't work with IE or Safari. // $('#searchSubmit').click(); } } function windowOpenFailedMsg() { alert("Your web browser prevented us from opening a new window.\n\nPlease change your browser settings to allow pop-up windows from " + document.domain + "."); } function updateVisibility(track, visibility) { -// Updates visibility state in trackDbJson and any visible elements on the page. +// 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 = trackDbJson[track]; + var rec = hgTracks.trackDb[track]; var selectUpdated = false; $("select[name=" + track + "]").each(function(t) { $(this).attr('class', visibility == 'hide' ? 'hiddenText' : 'normalText'); $(this).val(visibility); selectUpdated = true; }); if(rec) { rec.localVisibility = visibility; } return selectUpdated; } function getVisibility(track) { // return current visibility for given track - var rec = trackDbJson[track]; + var rec = hgTracks.trackDb[track]; if(rec) { if(rec.localVisibility) { return rec.localVisibility; } else { return visibilityStrsOrder[rec.visibility]; } } else { return null; } } function makeSureSuggestTrackIsVisible() { // make sure to show knownGene/refGene track is in at least pack (redmine #3484). var track = $("#suggestTrack").val();