My aggregated monorepo of OCaml code, automaintained
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix mermaid and dot SPA: poll for CDN script load

On SPA navigation, the MutationObserver fires when content is swapped
but the CDN scripts (mermaid.js, viz.js) may not have loaded yet.
renderAll() returns early since the global isn't defined. When the
CDN script finally loads, there's no further mutation to trigger
renderAll().

Fix: when pending elements exist but the CDN library isn't loaded,
start polling (200ms interval) until it becomes available, then
render.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+41 -4
+19 -2
odoc-dot-extension/src/dot_extension.ml
··· 156 156 } 157 157 158 158 function observe() { 159 - new MutationObserver(function() { renderAll(); }) 160 - .observe(document.body, { childList: true, subtree: true }); 159 + new MutationObserver(function() { 160 + renderAll(); 161 + if (typeof Viz === 'undefined' && 162 + document.querySelectorAll('.odoc-dot-diagram:not([data-dot-init])').length > 0) { 163 + waitForViz(); 164 + } 165 + }).observe(document.body, { childList: true, subtree: true }); 166 + } 167 + 168 + var waitTimer = null; 169 + function waitForViz() { 170 + if (waitTimer) return; 171 + waitTimer = setInterval(function() { 172 + if (typeof Viz !== 'undefined') { 173 + clearInterval(waitTimer); 174 + waitTimer = null; 175 + renderAll(); 176 + } 177 + }, 200); 161 178 } 162 179 })(); 163 180 |}
+22 -2
odoc-mermaid-extension/src/mermaid_extension.ml
··· 259 259 } 260 260 261 261 function observe() { 262 - new MutationObserver(function() { renderAll(); }) 263 - .observe(document.body, { childList: true, subtree: true }); 262 + new MutationObserver(function() { 263 + renderAll(); 264 + // If mermaid isn't loaded yet but there are pending elements, 265 + // poll until it loads (handles SPA where mermaid CDN script 266 + // loads after content swap). 267 + if (typeof mermaid === 'undefined' && 268 + document.querySelectorAll('pre.mermaid:not([data-mermaid-init])').length > 0) { 269 + waitForMermaid(); 270 + } 271 + }).observe(document.body, { childList: true, subtree: true }); 272 + } 273 + 274 + var waitTimer = null; 275 + function waitForMermaid() { 276 + if (waitTimer) return; 277 + waitTimer = setInterval(function() { 278 + if (typeof mermaid !== 'undefined') { 279 + clearInterval(waitTimer); 280 + waitTimer = null; 281 + renderAll(); 282 + } 283 + }, 200); 264 284 } 265 285 })(); 266 286 |}