835f3f2b9a18f63af202b71477744469e647b328 jcasper Tue Jul 21 08:32:17 2026 -0700 Moving track description link to a more visible place and fixing hub ID parsing. Old method (parsing trackHubs cart variable) was failing as the contents can now be hubId:chainId (for quickLift). New approach uses a library function. refs #36320 diff --git src/hg/hgTrackUi/hgTrackUi.c src/hg/hgTrackUi/hgTrackUi.c index 842e8d53a84..6eb860710ac 100644 --- src/hg/hgTrackUi/hgTrackUi.c +++ src/hg/hgTrackUi/hgTrackUi.c @@ -3874,30 +3874,42 @@ safef(longLabel, sizeof(longLabel), "%s - Annotation Release %s", tdb->longLabel, trackVersion->version); } else safef(longLabel, sizeof(longLabel), "%s", tdb->longLabel); } printf("<B style='font-size:200%%;'>%s%s</B>\n", longLabel, tdbIsSuper(tdb) ? " Tracks" : ""); } else { if (trackDbSetting(tdb, "wgEncode")) printf("<A HREF='/ENCODE/index.html'><IMG style='vertical-align:middle;' " "width=100 src='/images/ENCODE_scaleup_logo.png'><A>"); // set large title font size, but less so for long labels to minimize wrap printf("<B style='font-size:%d%%;'>%s%s</B>\n", strlen(tdb->longLabel) > 30 ? 133 : 200, tdb->longLabel, tdbIsSuper(tdb) ? " tracks" : ""); + + // Add a description link if there is one. Only for faceted composites for now. + if (isNotEmpty(tdb->html) && (tdbIsComposite(tdb) && sameOk(trackDbLocalSetting(tdb, "compositeTrack"), "faceted"))) + { + char *downArrow = "⇓"; + enum browserType browser = cgiBrowser(); + if (browser == btIE || browser == btFF) + downArrow = "↓"; + printf(" (<A HREF='#TRACK_HTML' TITLE='Jump to description section of page'>" + "Description%s</A>)", downArrow); + } + } /* Print link for parent track */ if (!ajax) { if (!tdb->parent) { // show group info struct grp *grp, *grps = hLoadGrps(database); for (grp = grps; grp != NULL; grp = grp->next) { if (sameString(grp->name,tdb->grp)) { printf(" <B style='font-size:100%%;'>" @@ -4095,44 +4107,30 @@ downArrow = "↓"; printf(" <A HREF='#DISPLAY_SUBTRACKS' TITLE='Jump to subtrack list section of " "page'>Subtracks%s</A>", downArrow); if (isNotEmpty(tdb->html)) { printf(" <A HREF='#TRACK_HTML' TITLE='Jump to description section of page'>" "Description%s</A>", downArrow); } if (trackDbSetting(tdb, "wgEncode") && isEncode2(database, tdb->track)) { printf(" <A HREF='#TRACK_CREDITS' TITLE='Jump to ENCODE lab contacts for this data'>" "Contact%s</A>", downArrow); } printf(" </span>"); } - else if (tdbIsComposite(tdb) && sameOk(trackDbLocalSetting(tdb, "compositeTrack"), "faceted")) - { - char *downArrow = "⇓"; - enum browserType browser = cgiBrowser(); - if (browser == btIE || browser == btFF) - downArrow = "↓"; - if (isNotEmpty(tdb->html)) - { - printf("\n <span id='navDown' style='float:right; display:none;'>"); - printf(" <A HREF='#TRACK_HTML' TITLE='Jump to description section of page'>" - "Description%s</A>", downArrow); - printf(" </span>"); - } - } } if (!tdbIsSuperTrack(tdb) && !tdbIsComposite(tdb)) puts("<BR>"); if (tdbIsDownloadsOnly(tdb)) // Composites without tracks but with files to download filesDownloadUi(database,cart,tdb); // are tdb->type: downloadsOnly else specificUi(tdb, tdbList, ct, ajax); // Decorator UI struct slName *decoratorSettings = trackDbSettingsWildMatch(tdb, "decorator.*"); if (decoratorSettings) { char *browserVersion; if (btIE == cgiClientBrowser(&browserVersion, NULL, NULL) && *browserVersion < '8') @@ -4338,44 +4336,40 @@ * it as the page content. */ { char *genome = NULL; getDbAndGenome(cart, &database, &genome, NULL); initGenbankTableNames(database); char *fileUrl = cartOptionalString(cart, "fileUrl"); char *urlClone = cloneString(fileUrl); cgiDecode(urlClone, urlClone, strlen(urlClone)); fileUrl = resolveDotDots(urlClone); freeMem(urlClone); boolean matchFound = FALSE; // Check if fileUrl falls under a connected hub's base directory -struct slName *hubIds = hubConnectHubsInCart(cart); -struct slName *thisHubId = hubIds; -while (thisHubId != NULL) - { - struct hubConnectStatus *hubStatus = hubFromIdNoAbort(sqlUnsigned(thisHubId->name)); - if (hubStatus != NULL) +struct hubConnectStatus *hubStatusList = hubConnectStatusListFromCartAll(cart); +struct hubConnectStatus *hubStatus = hubStatusList; +while (hubStatus != NULL) { if (isEmpty(hubStatus->errorMessage) && fileUrlMatchesHub(fileUrl, hubStatus)) { matchFound = TRUE; break; } - } - thisHubId = thisHubId->next; + hubStatus = hubStatus->next; } // For native database tracks (not hub or custom tracks), check if fileUrl matches // a whitelisted trackDb setting. Only native tracks are checked here because their // settings are admin-configured and trusted. Hub and custom track settings are // user-controlled and could be used for SSRF attacks. if (!matchFound) { char *track = cartOptionalString(cart, "track"); char *sourceDb = cartOptionalString(cart, "sourceDb"); // for future quickLift use if (sourceDb == NULL) sourceDb = database; if (track != NULL && !isHubTrack(track) && !isCustomTrack(track)) { struct trackDb *tdb = tdbForTrack(sourceDb, track, NULL);