this repo has no description
0
fork

Configure Feed

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

Fix scrollycode SPA navigation bug and add extensions authoring guide

The scrollycode JS runtime was embedded as an inline <script> in the
page body, which the SPA navigator never executes. Moved it to a
registered support file (extensions/scrollycode.js) loaded via Js_url
in <head>, with a MutationObserver to detect new containers inserted
by SPA content swaps.

Added a new "Writing Extensions" doc page to odoc covering the
extension API, resource types, the SPA navigation pitfall, and the
scrollycode fix as a case study.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+29 -12
+29 -12
src/scrollycode_extension.ml
··· 537 537 }); 538 538 } 539 539 540 - // Initialize all scrollycode containers on the page 541 - document.addEventListener('DOMContentLoaded', function() { 542 - document.querySelectorAll('.sc-container').forEach(initScrollycode); 543 - }); 540 + // Initialize any uninitialised scrollycode containers. 541 + function initAll() { 542 + document.querySelectorAll('.sc-container').forEach(function(c) { 543 + if (!c.dataset.scInit) { 544 + c.dataset.scInit = '1'; 545 + initScrollycode(c); 546 + } 547 + }); 548 + } 549 + 550 + // Run now if DOM is ready, otherwise wait. 551 + if (document.readyState === 'loading') { 552 + document.addEventListener('DOMContentLoaded', function() { 553 + initAll(); 554 + // Watch for new containers added by SPA navigation. 555 + new MutationObserver(function() { initAll(); }) 556 + .observe(document.body, { childList: true, subtree: true }); 557 + }); 558 + } else { 559 + initAll(); 560 + new MutationObserver(function() { initAll(); }) 561 + .observe(document.body, { childList: true, subtree: true }); 562 + } 544 563 })(); 545 564 |} 546 565 ··· 695 714 </div> 696 715 |}; 697 716 698 - (* JavaScript *) 699 - Buffer.add_string buf "<script>\n"; 700 - Buffer.add_string buf shared_js; 701 - Buffer.add_string buf "</script>\n"; 702 - 703 717 Buffer.contents buf 704 718 705 719 (** {1 Extension Registration} *) ··· 734 748 overrides = []; 735 749 resources = [ 736 750 Css_url "extensions/scrollycode.css"; 751 + Js_url "extensions/scrollycode.js"; 737 752 Js_inline (meta_tag_script "x-ocaml-backend" "jtw"); 738 753 Js_inline (meta_tag_script "x-ocaml-worker" x_ocaml_worker_url); 739 754 Js_url "_x-ocaml/x-ocaml.js"; ··· 742 757 } 743 758 end 744 759 745 - (* Register extension and structural CSS support file. 746 - Force-link Scrollycode_themes to ensure theme support files are registered. *) 760 + (* Register extension and structural CSS support file. *) 747 761 let () = 748 - ignore (Scrollycode_themes.warm_css : string); 749 762 Odoc_extension_api.Registry.register (module Scrolly); 750 763 Odoc_extension_api.Registry.register_support_file ~prefix:"scrolly" { 751 764 filename = "extensions/scrollycode.css"; 752 765 content = Inline Scrollycode_css.structural_css; 766 + }; 767 + Odoc_extension_api.Registry.register_support_file ~prefix:"scrolly" { 768 + filename = "extensions/scrollycode.js"; 769 + content = Inline shared_js; 753 770 }; 754 771 (* Find x-ocaml.js: env var, then dune build install dir (walk up from CWD). *) 755 772 let x_ocaml_js_path =