Skip to content

Commit b55a31e

Browse files
authored
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: #32392 <img width="885" alt="image" src="https://github.com/user-attachments/assets/a95ef6aa-27e7-443f-9d06-400ef27919ae">
1 parent 18aeca5 commit b55a31e

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

web_src/js/markup/mermaid.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,21 @@ export async function renderMermaid() {
5757
btn.setAttribute('data-clipboard-text', source);
5858
mermaidBlock.append(btn);
5959

60+
const updateIframeHeight = () => {
61+
iframe.style.height = `${iframe.contentWindow.document.body.clientHeight}px`;
62+
};
63+
64+
// update height when element's visibility state changes, for example when the diagram is inside
65+
// a <details> + <summary> block and the <details> block becomes visible upon user interaction, it
66+
// would initially set a incorrect height and the correct height is set during this callback.
67+
(new IntersectionObserver(() => {
68+
updateIframeHeight();
69+
}, {root: document.documentElement})).observe(iframe);
70+
6071
iframe.addEventListener('load', () => {
6172
pre.replaceWith(mermaidBlock);
6273
mermaidBlock.classList.remove('tw-hidden');
63-
iframe.style.height = `${iframe.contentWindow.document.body.clientHeight}px`;
74+
updateIframeHeight();
6475
setTimeout(() => { // avoid flash of iframe background
6576
mermaidBlock.classList.remove('is-loading');
6677
iframe.classList.remove('tw-invisible');

0 commit comments

Comments
 (0)