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("%s%s\n", longLabel, tdbIsSuper(tdb) ? " Tracks" : "");
}
else
{
if (trackDbSetting(tdb, "wgEncode"))
printf("
");
// set large title font size, but less so for long labels to minimize wrap
printf("%s%s\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(" ("
+ "Description%s)", 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(" "
@@ -4095,44 +4107,30 @@
downArrow = "↓";
printf(" Subtracks%s", downArrow);
if (isNotEmpty(tdb->html))
{
printf(" "
"Description%s", downArrow);
}
if (trackDbSetting(tdb, "wgEncode") && isEncode2(database, tdb->track))
{
printf(" "
"Contact%s", downArrow);
}
printf(" ");
}
- 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 ");
- printf(" "
- "Description%s", downArrow);
- printf(" ");
- }
- }
}
if (!tdbIsSuperTrack(tdb) && !tdbIsComposite(tdb))
puts("
");
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);