cee097b75fe4d1b29f0debd8af938ba6bf729d53 max Tue Aug 11 08:18:42 2026 -0700 hgBlat: new client-rendered BLAT search form and sortable results page, refs #37893 An opt-in modern alternative to the classic hyperlink output, gated by the blatNewForm / blatNewPage hg.conf flags. hgBlat.c emits the hit data and form config as inline JSON (hgBlatData / hgBlatFormData) into empty containers, and hgBlat.js builds the UI: the search form, a sortable/filterable DataTable with identity and query-coverage bars, a docked per-hit detail panel, a FASTA query viewer, and share-link and rename-track modals. - hgBlat.css: all styling for both pages, loaded via webIncludeResourceFile (not injected from JS); layout uses CSS classes rather than inline styles. - utils.js: setupGenomeSelector, the combobox genome picker the form uses. - hgc.c: blatOldTracks / blatKeepResults - the "Keep results" checkbox lets a user accumulate BLAT result tracks instead of each search replacing the last. - hgConfCatalog: register the blatNewForm / blatNewFormBanner gates. - blatExample.fa: the example query the form loads on demand. Markup is built in JS (escaped values via htmlEncode, everything else set through DOM properties); no HTML strings in the C or a template engine. diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c index 98409105b14..48bfe4d4b8e 100644 --- src/hg/hgc/hgc.c +++ src/hg/hgc/hgc.c @@ -27516,30 +27516,34 @@ * keep (default) - do nothing, every search's track stays as-is * hide - leave earlier BLAT tracks in the session but set them to hide * delete - remove earlier BLAT tracks from the session (their trash files age out) * Only BLAT-tagged tracks are touched; the track just made is left alone. */ char *oldTracks = cfgOptionDefault("blatOldTracks", "keep"); /* Fail safe on an unrecognized value (e.g. a typo in hg.conf): fall back to "keep" rather than to * the destructive "delete" branch below, so a misconfiguration never silently discards a user's * previous BLAT tracks. */ if (differentString(oldTracks, "keep") && differentString(oldTracks, "hide") && differentString(oldTracks, "delete")) { warn("hg.conf blatOldTracks has unrecognized value '%s'; expected keep|hide|delete. " "Treating as 'keep'.", oldTracks); oldTracks = "keep"; } +/* The BLAT search form shows a "Keep results" checkbox when this is set to "delete", letting the + * user opt out per search; blatKeepResults is the cart variable it sets. */ +if (cartUsualBoolean(cart, "blatKeepResults", FALSE)) + oldTracks = "keep"; if (differentString(oldTracks, "keep")) { struct customTrack *ct, *next, *keptList = NULL; for (ct = ctList; ct != NULL; ct = next) { next = ct->next; if (ct->tdb != NULL && sameOk(trackDbSetting(ct->tdb, "blatResult"), "on")) { if (sameString(oldTracks, "hide")) { cartSetString(cart, ct->tdb->track, "hide"); slAddHead(&keptList, ct); /* keep it in the session, just hidden */ } /* "delete": drop it from the list so customTracksSaveCart writes it out */ }