e2c6af507b9d46c00083b9d560f643ee5f74e688 max Fri Sep 25 13:11:31 2026 -0700 hgSearch: fix JS error clicking MANE search result links, refs #38285 diff --git src/hg/js/hgSearch.js src/hg/js/hgSearch.js index c775ea590b9..0405e8629f7 100644 --- src/hg/js/hgSearch.js +++ src/hg/js/hgSearch.js @@ -883,31 +883,34 @@ // reload the page to attach curated hub (if any) re = /db=[\w,\.]*/; window.location = window.location.href.replace(re,"db="+newDb); } function saveLinkClicks() { // attach the link handlers to save search history document.querySelectorAll(".searchResult>a").forEach(function(i,j,k) { i.addEventListener("click", function(e) { // i is the <a> element, use parent elements and the href // to construct a fake autocomplete option and save it e.preventDefault(); // stops the page from redirecting until this function finishes let callbackData = {}; let trackName = i.parentNode.parentNode.parentNode.id.replace(/Results$/,""); let matchList = uiState.positionMatches.find((matches) => matches.name === trackName); - let id, match, matchStr = i.childNodes[0].textContent; + // use the full link text, not just the first child node: a MANE + // transcript link has a "MANE Select: " text node before the + // bolded accession, so childNodes[0] alone would miss the accession + let id, match, matchStr = i.textContent; // switch lookup depending on the different search categories: let decoder = function(str) { // helper decoder to change the html encoded entities in // uiState.positionMatches.posName to what is actually rendered // in matchStr return $("<textarea/>").html(str).text(); }; let geneSymbol; // a potentially fake geneSymbol for the autoComplete if (trackName === "trackDb") { match = matchList.matches.find((elem) => { let posSplit = elem.posName.split(":"); geneSymbol = decoder(posSplit[1] + " - " + posSplit[2]); id = "hgTrackUi?db=" + uiState.db + "&g=" + posSplit[0]; return geneSymbol === matchStr; }); @@ -929,32 +932,39 @@ callbackData.geneSymbol = geneSymbol; callbackData.internalId = ""; } else if (trackName === "helpDocs") { match = matchList.matches.find((elem) => { let posSplit = elem.posName.split(":"); geneSymbol = decoder(posSplit[1].replaceAll("_", " ")); return geneSymbol === matchStr; }); callbackData.label = geneSymbol; callbackData.value = geneSymbol; callbackData.id = match.position.split(":")[0]; callbackData.geneSymbol = geneSymbol; callbackData.internalId = ""; } else { // regular track item search result click match = matchList.matches.find((elem) => { + // mirror the title construction in printMatches(): a MANE + // transcript is displayed as its protein accession (optionally + // prefixed with the MANE status), not the raw posName + let title = elem.maneProtAcc ? elem.maneProtAcc : elem.posName; + if (elem.maneStatus) { + title = elem.maneStatus + ": " + title; + } geneSymbol = elem.posName.replace(/ .*$/,""); - return decoder(elem.posName) === matchStr; + return decoder(title) === matchStr; }); callbackData.label = geneSymbol; callbackData.value = geneSymbol; // special case the genbank searches that are supposed to go to hgc // and not hgTracks let parentTitle = i.parentNode.parentNode.parentNode.childNodes[2]; if (["all_mrna", "all_est", "xenoMrna", "xenoEst", "intronEst"].includes(trackName) && parentTitle.textContent.includes("Unaligned")) { id = "hgc?db=" + db + "&g=" + trackName+ "&i=" + match.position + "&c=0&o=0&l=0&r=0" ; } else { id = match.position; } callbackData.id = id; callbackData.geneSymbol = geneSymbol; callbackData.internalId = match.hgFindMatches; }