fix(preview): a theme change re-draws the diagrams it has never re-drawn (#741), retargeted to master - #743
Merged
Merged
Conversation
…awn (#741) Mermaid bakes fills, strokes and label colours into the SVG, so a theme change has to draw the diagrams again. The theme effect called `renderRichContent()` to do exactly that, and it has not worked since #632: that function finds diagrams by `pre code`, and a diagram that has been drawn once has no `<pre>` left -- `renderRichContent` itself replaced it with the `.mermaid-diagram` container. While the preview was `{@html sanitizedHtml}` every render put the whole document back as source and the selector matched; `blockPatch.ts` keeps enriched nodes across renders instead, and from then on a theme change reached no diagram at all, in any mode, for any theme. Nothing else covers it. Re-activating a tab patches to nothing, so `patch.inserted` is empty; typing does not help either, because the diagram's markup is unchanged and the patch keeps the node. `mermaidPrint.ts` already keeps the source on the container so the PDF path can rebuild a diagram with a light theme. The theme it was drawn with is now kept beside it, and `renderRichContent` re-draws the containers whose theme no longer matches the one it was asked for -- through the same cache, sanitizer and id factory as a fresh diagram, which is a `drawDiagram` the two paths share. The guard on the call was the second half. `if (markdownBody && !isEditing)` read `isEditing`, so the whole effect re-ran on every mode toggle and on every tab switch that changed the mode: the dataset writes, `monaco.editor.setTheme`, and for a `vscode:` theme an `invoke('read_vscode_theme')` and a re-parse, with nothing about the theme having moved. Nothing in the body wants a mode dependency -- Editor.svelte themes Monaco itself from its own `theme` prop. And the guard excluded from the re-colour every tab in edit mode, including a split tab entered from edit mode, whose preview is on screen beside the editor. The call is also made per branch rather than once at the end: the `vscode:` branch does not know its own appearance until `parseAndApplyVscodeTheme` has published `dataset.themeType`, which is what `currentMermaidTheme` reads, so the old placement would have re-drawn every diagram in the theme being replaced. Measured in Chromium as one whole-article pass with the other memos warm, two runs: diagrams theme moved theme unchanged samples/katex-stress.md 0 8.6-10.6ms 11.9-12.2ms samples/markdown-syntax.md 4 61.2-76.1ms 2.6-3.0ms samples/stress-test.md 3 107.5-121.2ms 12.5-12.8ms The right-hand column is what a mode toggle used to pay to draw nothing. `untrack` stays, for the reason #740 established: a tracked call makes this effect re-run when the rich-content libraries land and duplicate the cold-start enrichment the patch effect owns.
…742) `monaco.editor.setTheme` is global to the page, and the viewer's theme effect set Monaco's stock `vs`/`vs-dark` over the `app-theme-*` the editor had just asked for — a child's effects run before its parent's, so the viewer's write landed last and stripped the editor of every markdown and semantic token rule on each theme change. The name is now decided once, in `editorTheme.ts`, and only `Editor.svelte` asks for it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Base is
master. Administrative: this is #741, already reviewed and merged,but into
perf/rich-content-anchor-driftrather than intomaster, because thatbranch was its base while #740 was open. #740 was squash-merged to
master,which closed the branch's own PR and left this sitting where nothing points at
it. Cherry-picked onto
master; the commit below is the same one. Same thinghappened to #732-#735 earlier in this series (#737).
Rebasing the branch instead does not work: #740's own commit conflicts against
its squash on
master, which is the same content under a different SHA.What is in here
A theme change never re-drew a Mermaid diagram, in any mode, for any theme, and
had not since #632.
renderRichContentfinds diagrams withselfAndDescendants(root, 'pre code'),and a diagram that has been drawn once has no
<pre>left — that same functionreplaced it with
<div class="mermaid-diagram">. While the preview was{@html sanitizedHtml}this was invisible, because every render put the wholedocument back as source and the diagram was rebuilt from scratch.
blockPatch.tskeeps the enriched nodes instead, so from #632 on the theme change reached
nothing. Mermaid bakes its colours into the SVG, so a dark diagram stayed dark on
a light page indefinitely.
The source was already on the container —
mermaidPrint.tskeeps it there so thePDF path can rebuild the diagram light — so the theme it was drawn for is kept
beside it, and
renderRichContentnow collects the containers whose theme nolonger matches and re-draws them through a
drawDiagramboth paths share. Thecollection runs before the
pre codeloop so the containers that loop is aboutto build are not scanned as stale.
The viewer's theme effect also stopped depending on
isEditing. It was a trackedread, so every ⌘E and every mode-changing tab switch re-ran the whole theme block
—
datasetwrites,clearVscodeTheme,saveStartupAppearance,monaco.editor.setTheme, and for avscode:theme aninvoke('read_vscode_theme')round trip plus a re-parse — to draw no diagram at all.
git log -Sputs thatguard at 06380bc, where enrichment was a whole-document pass on every render and
the preview was hidden in edit mode: it was protecting something real then. Its
sibling lost the guard when the patch effect was built; this copy was never
revisited.
Measured in Chromium over the real pipeline, one whole-article pass with the
other memos warm, two runs:
The diagrams are the whole cost; katex-stress has none and its two columns agree.
The right-hand column is what a mode toggle used to pay to draw nothing.
Tests
scripts/diagramThemeRefresh.spec.tsdrivesrenderRichContenttwice against arecording Mermaid stand-in — a behaviour test, not a source assertion. Reverting
the re-draw with the tests kept turns 4 of its 5 red.
Two assertions from #740 went red on this change and were updated rather than
relaxed:
mermaidPrintTheme.test.tspinnedrememberDiagramSource's arity andpreviewAnchorRestore.test.tspinned a whole guard line when what it is for isthe
untrack. That is the "pins today's spelling" weakness #740's own bodycalled out, arriving one PR later.
Verification
Re-run after the cherry-pick. The app cannot be run here: worth toggling
light/dark with a document containing a Mermaid diagram open before this lands.