fix(visimer): stop cold-load webfonts from clipping node labels (#3560) - #33
Merged
Conversation
* fix(visimer): stop cold-load webfonts from clipping node labels Mermaid measures label text against the fonts the document can use at the moment it renders, then bakes those measurements into fixed-width foreignObject boxes. On a first visit the webfont is still in flight behind font-display: swap, so the boxes are sized for the fallback and the real text overflows them once it swaps in. Every node label ends up clipped a few pixels short: "Tests green?" loses its "?", "Ship it" reads "Ship i", "Fix bugs" reads "Fix bug". Nothing in mermaid or in the browser re-measures, so the diagram stays wrong for the whole session, and any reload hides it because the font is cached by then. That is why it never shows up in development and shows up for every first-time visitor. MermaidCanvasView now looks at document.fonts after each render. If the document's fonts are still loading it waits for them to settle and renders again, which re-measures every label against the fonts the browser is actually painting with. Checking after the render matters: mermaid's own measuring pass is usually what first requests the webfont, so the pending load is only visible by then. The wait arms only while fonts are pending, so a page whose fonts are already available renders exactly once, as before, and it cannot loop because the corrective render runs with the status already settled. The fix is in the library rather than in apps/site because any embedder of @visimer/dom that uses a webfont hits this, and the view is the only layer that can act on it: it owns the render loop and the lastRenderedCode short-circuit a correction has to bypass. Measured with Playwright on a cold browser context against the dev site: 7 of 7 labels on the landing page and 3 of 4 on the playground were clipped before, 0 after, and the cold-load box geometry now matches the warm-cache geometry exactly. * fix(visimer): make the font-settled path explicit and pin the arm-once guard Review follow-ups on the cold-load font fix. The re-measure now routes both promise settlements through one named handler instead of swallowing rejection in a bare catch. FontFaceSet.ready is spec'd never to reject, but a partial polyfill could, and either way the measurements are as final as they are going to get, so both paths should re-render. Adds a test for the arm-once guard. The existing tests all render once before the fonts settle, so they pass even with the guard removed. The new one renders twice while fonts are still loading and asserts a single corrective render, which fails with 4 renders when the guard is dropped. GitOrigin-RevId: 82fe42e2c9fa3470ab2c3be9afd5ca93ff6e1406
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.
Copybara-translated 1 Inkeep OSS change. Rebase-merge this PR so the prepared commit lands directly on public main.