d99ea622f4024a17ea2cb5dbb4a4d81fd14395c7 jcasper Mon Mar 16 10:05:34 2026 -0700 Moving cartDump vis adjustments for faceted tracks into its own function, per request. refs #37090 diff --git src/hg/cartDump/cartDump.c src/hg/cartDump/cartDump.c index 43fde324e08..f959fb22f23 100644 --- src/hg/cartDump/cartDump.c +++ src/hg/cartDump/cartDump.c @@ -7,76 +7,48 @@ #include "hash.h" #include "cheapcgi.h" #include "cart.h" #include "hdb.h" #include "jsHelper.h" #include "hui.h" #include "botDelay.h" /* for earlyBotCheck() function at the beginning of main() */ #define delayFraction 1.0 /* standard penalty for most CGIs */ static boolean issueBotWarning = FALSE; #define CART_DUMP_REMOVE_VAR "n/a" struct hash *oldVars = NULL; -void doMiddle(struct cart *cart) -/* cartDump - Dump contents of cart. */ +void handleFacets(struct cart *cart) +/* Process track vis updates for a faceted composite. This uses information about + * which data types (dt) and data elements (de) were on before and after the + * user made UI changes. If data types are used by the track, they're usually + * things like "reads" and "signals". Data elements are generally either sample + * IDs (if data types are also used) or just the ends of track names. + * + * If the user adds a new data element, we turn on all associated tracks for the + * active data types. If a user adds a new data type, we turn on all associated + * tracks for the active data elements. But if a data element/type combo was already + * checked, we don't re-enable that track because the user might have hidden it + * manually. + */ { -#define MATCH_VAR "match" - -char *vName = "cartDump.varName"; -char *vVal = "cartDump.newValue"; char *mName = "cartDump.metaDataId"; -char *wildcard; -boolean asTable = cartVarExists(cart,CART_DUMP_AS_TABLE); - -if (cgiVarExists("submit")) - { - char *varName = cgiOptionalString(vName); - char *newValue = cgiOptionalString(vVal); - if (isNotEmpty(varName) && isNotEmpty(newValue)) - { - varName = skipLeadingSpaces(varName); - eraseTrailingSpaces(varName); - if (sameString(newValue, CART_DUMP_REMOVE_VAR) || sameString(newValue, CART_VAR_EMPTY)) - cartRemove(cart, varName); - else - cartSetString(cart, varName, newValue); - } - cartRemove(cart, vVal); - cartRemove(cart, "submit"); - } -if (cgiVarExists("noDisplay")) - { - // update cart vars for a track, called by hgTracks.js and ajax.js - // not useful to hackers, so there is no need to call bottleneck. - char *trackName = cgiOptionalString("g"); - if (trackName != NULL && hashNumEntries(oldVars) > 0) - { - char *db = cartString(cart, "db"); - struct trackDb *tdb = hTrackDbForTrack(db, trackName); - if (tdb != NULL && tdbIsComposite(tdb)) - { - struct lm *lm = lmInit(0); - cartTdbTreeCleanupOverrides(tdb,cart,oldVars,lm); - lmCleanup(&lm); - } - } +if (!cgiVarExists(mName)) + return; - if (cgiVarExists(mName)) - { char *mdid = cgiOptionalString(mName); char mdid_de_was[1024], mdid_de_now[1024], mdid_dt_was[1024], mdid_dt_now[1024]; safef(mdid_de_was, sizeof(mdid_de_was), "%s.de_was", mdid); safef(mdid_de_now, sizeof(mdid_de_now), "%s.de_now", mdid); safef(mdid_dt_was, sizeof(mdid_dt_was), "%s.dt_was", mdid); safef(mdid_dt_now, sizeof(mdid_dt_now), "%s.dt_now", mdid); // Grab the lists of which de/dt elements were on before and after the user // changed settings around struct slName *de_was_list = cgiStringList(mdid_de_was); struct slName *de_now_list = cgiStringList(mdid_de_now); struct slName *dt_was_list = cgiStringList(mdid_dt_was); struct slName *dt_now_list = cgiStringList(mdid_dt_now); // For faster lookup struct hash *de_was_hash = hashFromSlNameList(de_was_list); @@ -161,30 +133,74 @@ hashFree(&dt_was_hash); hashFree(&dt_now_hash); slFreeList(&de_was_list); slFreeList(&de_now_list); slFreeList(&dt_was_list); slFreeList(&dt_now_list); cartRemove(cart, mName); cartRemove(cart, mdid_de_was); cartRemove(cart, mdid_de_now); cartRemove(cart, mdid_dt_was); cartRemove(cart, mdid_dt_now); } + +void doMiddle(struct cart *cart) +/* cartDump - Dump contents of cart. */ +{ +#define MATCH_VAR "match" + +char *vName = "cartDump.varName"; +char *vVal = "cartDump.newValue"; +char *wildcard; +boolean asTable = cartVarExists(cart,CART_DUMP_AS_TABLE); + +if (cgiVarExists("submit")) + { + char *varName = cgiOptionalString(vName); + char *newValue = cgiOptionalString(vVal); + if (isNotEmpty(varName) && isNotEmpty(newValue)) + { + varName = skipLeadingSpaces(varName); + eraseTrailingSpaces(varName); + if (sameString(newValue, CART_DUMP_REMOVE_VAR) || sameString(newValue, CART_VAR_EMPTY)) + cartRemove(cart, varName); + else + cartSetString(cart, varName, newValue); + } + cartRemove(cart, vVal); + cartRemove(cart, "submit"); + } +if (cgiVarExists("noDisplay")) + { + // update cart vars for a track, called by hgTracks.js and ajax.js + // not useful to hackers, so there is no need to call bottleneck. + char *trackName = cgiOptionalString("g"); + if (trackName != NULL && hashNumEntries(oldVars) > 0) + { + char *db = cartString(cart, "db"); + struct trackDb *tdb = hTrackDbForTrack(db, trackName); + if (tdb != NULL && tdbIsComposite(tdb)) + { + struct lm *lm = lmInit(0); + cartTdbTreeCleanupOverrides(tdb,cart,oldVars,lm); + lmCleanup(&lm); + } + } + handleFacets(cart); return; } // To discourage hacking, call bottleneck if (issueBotWarning) { char *ip = getenv("REMOTE_ADDR"); botDelayMessage(ip, botDelayMillis); } if (asTable) { jsIncludeFile("jquery.js",NULL); // required by utils.js jsIncludeFile("utils.js",NULL); jsIncludeFile("ajax.js",NULL);