JavaScript: Ensure workspace is collapsed when solution is revealed - #3151
JavaScript: Ensure workspace is collapsed when solution is revealed#3151kylemonette wants to merge 2 commits into
Conversation
|
Follow-up: Revealing a solution can also free up space, not just use it The previous fix made workspace collapse once a solution is shown. But Showing a solution can now shrink a page too, because the workspace collapses at the same time. So a page that had already spilled its content onto a new page can end up with room to fit that content back. Both showing and hiding now try to pull spilled-over content back onto the previous page first, and only push content to a new page if it still doesn't fit. This is safe in both directions because pulling content back only happens if it actually fits (from the previous fix). |
|
Some of the work here might be subsumed by that of #3154, which should be merged first I think. |
This PR deals with two workspace/solution-pagination fixes, continuing off the changes made in PR #3114 .
Workspace didn't collapse when a solution was revealed
Workspace was always stretched to fill unused space on the page, even after the question's hint/answer/solution had been revealed. This left a large gap between a question and its "Solution" block.
Embedded videos reloaded unnecessarily during repagination
Toggling solution visibility triggers a settle loop that can move page rows (and therefore any
<iframe>inside them) between.onepagecontainers several times before layout stabilizes. Each move caused the iframe to reload, so a single checkbox toggle could reload a video multiple times.New functions:
anySolutionTypeVisible()— Returns whether any hint/answer/solution is currently visible on the page. Checks effective visibility (the element itself and every ancestor free of thehiddenclass), not just:not(.hidden)on the element alone. This distinction matters because a live PreTeXt knowl nests its content in a.knowl__contentdiv that never carrieshiddendirectly — only its.born-hidden-knowlancestor wrapper does. A naive:not(.hidden)check matches that inner div regardless of the collapsed ancestor, which caused every workspace on a page to incorrectly read as "a solution is visible" from the moment the page loaded, before the reader had revealed anything.withIframesDetached(fn)— Wraps a batch of repagination work. Detaches every<iframe>in the printout (swapping each for a same-sized placeholder div, so height measurements stay accurate) beforefnruns, then reattaches them oncefnresolves. This caps a solution-visibility toggle at reloading an embedded video once, instead of once per intermediate row move during the settle loop.Modified functions:
setInitialWorkspaceHeights()— Now collapses workspace to0pxinstead of its authored height wheneveranySolutionTypeVisible()is true, freeing that space for pagination once it's no longer needed as blank writing room.adjustWorkspaceToFitPage()— Skips the pass that stretches workspace boxes to fill unused page space wheneveranySolutionTypeVisible()is true, leaving workspace at its (now-collapsed) authored height instead.collapseSpilloverPages()— Once a solution is visible, workspace is pinned at its collapsed floor and will never shrink further, so the normal "merge first, let the caller re-split if it doesn't fit" order no longer converges — it just oscillates every settle tick. This function now checks fit before merging in that case (via a newworkspaceIsFixedflag), and puts a spillover page's content back rather than flip-flopping if it doesn't actually fit.applySolutionVisibility()— The whole toggle body now runs insidewithIframesDetached(), since the repagination/collapse work it triggers can move a row several times over the course of one toggle.