fbbc2d15114548cc241e4b99dc83c0c9e79310ac braney Tue Jul 28 10:20:22 2026 -0700 Docent: take track state from trackDb, add goShow, search the Convert target visibly refs #37892 Track visibility no longer comes from a table inside the renderer. docent.js used to carry per-composite cart parameters (mane/dbSnp155/clinvar), which pinned clinvarMain to dense for every clinvar step and quietly aliased dbSnp155 to a subtrack it does not name. It now reads the trackDb of the server it is driving (hubApi /list/tracks, cached a day in $TMPDIR) and derives what a step needs: the containers above a track, and the _sel checkbox that actually decides a composite child. Nothing is pushed downward, since a container's visibility already reaches its selected children, so a script names only its deviations from trackDb. Scripts use real trackDb names; names trackDb does not have (hubs, custom tracks, a quickLift target) are sent as a literal name=mode. Two hgTracks mechanics this had to learn: a bare clinvarCnv=hide is dropped when the container's visibility is in the same request (the cart keeps clinvarCnv_sel=1 and the row still draws), so a step naming both a composite and a child of it is applied in two requests, container first. New goShow verb: types a position or a GENE NAME into the position bar and lets the page finish -- Search on hgTracks, the arrow on hgGateway. A gene name goes through the browser's own suggestion menu, so it lands on the gene rather than the search-results page. pick: disambiguates the menu. convert: now finds the target the way a user does, by typing it into the Convert page's own genome search bar and clicking the suggestion, and accepts shot: for the Convert page itself (opened / filled / result), which no other verb can reach. Stills of pages that are not hgTracks (an hgc detail page, an external page a link led to) are the viewport -- the top of the page -- instead of an element shot of the whole scrolling document, which ran to 4400px. A fading click ripple is removed before a still: it belongs to the video, not to a figure. Speed: FAST=1 (make FAST=1 BP1, DOCENT_FAST=1, or fast: true) drops everything that exists only for the video -- dwells, cursor animation, dropdown theatrics, screen recording, mp4 transcode -- taking BP1 from 64s to 24s for the same figures. docent.mk documents make -j for parallel scenarios; the trackDb cache is written via rename so concurrent runs cannot read a partial file, and holds the derived index (3MB) rather than hubApi's reply (30MB). DOCENT_TIME=1 prints where the wall clock went, DOCENT_ROWS=1 the rows hgTracks actually drew. Trimming the dwells exposed a real race in mouseover: dismissing the previous tooltip with a sleep and then waiting for "a tooltip is visible" was satisfied by the stale one, so a back-to-back pinned mouseover captured the previous item's text. It now waits for the old tooltip to be gone and for a new one whose content differs. Co-Authored-By: Claude Opus 5 (1M context) diff --git src/hg/utils/docent/docent.mk src/hg/utils/docent/docent.mk index 85c7a7e0537..dfd6ef68d86 100644 --- src/hg/utils/docent/docent.mk +++ src/hg/utils/docent/docent.mk @@ -3,47 +3,54 @@ # A project that keeps a set of *.docent.yaml scripts includes this file and gets # incremental rebuilds: each ../.mp4 is regenerated when its own script — or # docent.js itself — is newer. docent.js writes the mp4 and the named stills in one # run, so the mp4 stands in for both as the make target. # # In the project's Makefile: # # DOCENT ?= $(HOME)/kent/src/hg/utils/docent/docent.js # include $(dir $(DOCENT))docent.mk # # then: # # make # build every mp4 whose script (or docent.js) changed # make AP1 # build just ../AP1.mp4 (if stale) # make -B AP2 # force a rebuild +# make FAST=1 BP1 # figures only, no video -- roughly a third of the wall clock +# make -j6 # scenarios in parallel (each run gets its own browser + cart) # make list # list the base names discovered # make clean # remove generated mp4s and stills/ # # Override before the include: FIGDIR (where mp4s land, default ..), PW_ENV (the # Playwright runtime), SCRIPTS/BASES (to build an explicit subset). DOCENT ?= $(HOME)/kent/src/hg/utils/docent/docent.js SCRIPTS ?= $(wildcard *.docent.yaml) BASES ?= $(SCRIPTS:.docent.yaml=) FIGDIR ?= .. MP4S := $(addprefix $(FIGDIR)/,$(addsuffix .mp4,$(BASES))) # Shared Playwright/Chromium install. Anywhere you have playwright + js-yaml works; # at UCSC this is the ~/pwrec tree. PW_ENV ?= PLAYWRIGHT_BROWSERS_PATH=$(HOME)/pwrec/browsers NODE_PATH=$(HOME)/pwrec/node_modules +# FAST=1 -> figures only: no dwells, no cursor animation, no screen recording, no mp4. +# Same stills, about a third of the wall clock. Use it while iterating on figure content; +# drop it for the final build that has to produce the videos. +FAST_ENV = $(if $(FAST),DOCENT_FAST=1 ,) + .PHONY: all list clean $(BASES) all: $(MP4S) $(FIGDIR)/%.mp4: %.docent.yaml $(DOCENT) - $(PW_ENV) node $(DOCENT) $< + $(FAST_ENV)$(PW_ENV) node $(DOCENT) $< # Convenience: `make AP1` -> build ../AP1.mp4 $(BASES): %: $(FIGDIR)/%.mp4 list: @echo $(BASES) clean: rm -f $(MP4S) rm -rf stills