From b55a31eb6a894feb5508e350ff5e9548b2531bd6 Mon Sep 17 00:00:00 2001 From: silverwind Date: Sat, 9 Nov 2024 19:03:55 +0100 Subject: [PATCH] Fix mermaid diagram height when initially hidden (#32457) In a hidden iframe, `document.body.clientHeight` is not reliable. Use `IntersectionObserver` to detect the visibility change and update the height there. Fixes: https://github.com/go-gitea/gitea/issues/32392 image --- web_src/js/markup/mermaid.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/web_src/js/markup/mermaid.ts b/web_src/js/markup/mermaid.ts index f2754e659b..5c27d6ca1c 100644 --- a/web_src/js/markup/mermaid.ts +++ b/web_src/js/markup/mermaid.ts @@ -57,10 +57,21 @@ export async function renderMermaid() { btn.setAttribute('data-clipboard-text', source); mermaidBlock.append(btn); + const updateIframeHeight = () => { + iframe.style.height = `${iframe.contentWindow.document.body.clientHeight}px`; + }; + + // update height when element's visibility state changes, for example when the diagram is inside + // a
+ block and the
block becomes visible upon user interaction, it + // would initially set a incorrect height and the correct height is set during this callback. + (new IntersectionObserver(() => { + updateIframeHeight(); + }, {root: document.documentElement})).observe(iframe); + iframe.addEventListener('load', () => { pre.replaceWith(mermaidBlock); mermaidBlock.classList.remove('tw-hidden'); - iframe.style.height = `${iframe.contentWindow.document.body.clientHeight}px`; + updateIframeHeight(); setTimeout(() => { // avoid flash of iframe background mermaidBlock.classList.remove('is-loading'); iframe.classList.remove('tw-invisible');