;; _hyperscript integration — wire _="..." attributes to compiled SX ;; ;; Entry points: ;; (hs-handler src) — compile source to callable (fn (me) ...) ;; (hs-activate! el) — activate hyperscript on a single element ;; (hs-boot!) — scan DOM, activate all _="..." elements ;; (hs-boot-subtree! root) — activate within a subtree (for HTMX swaps) ;; ── Compile source to a handler function ──────────────────────── ;; Returns a function (fn (me) ...) that can be called with a DOM element. ;; Uses eval-expr-cek to turn the SX data structure into a live closure. (define hs-handler (fn (src) (let ((sx (hs-to-sx-from-source src))) (eval-expr-cek (list (quote fn) (list (quote me)) (list (quote let) (list (list (quote it) nil) (list (quote event) nil)) sx)))))) ;; ── Activate a single element ─────────────────────────────────── ;; Reads the _="..." attribute, compiles, and executes with me=element. ;; Marks the element to avoid double-activation. (define hs-activate! (fn (el) (let ((src (dom-get-attr el "_"))) (when (and src (not (dom-get-data el "hs-active"))) (dom-set-data el "hs-active" true) (let ((handler (hs-handler src))) (handler el)))))) ;; ── Boot: scan entire document ────────────────────────────────── ;; Called once at page load. Finds all elements with _ attribute, ;; compiles their hyperscript, and activates them. (define hs-boot! (fn () (let ((elements (dom-query-all (dom-body) "[_]"))) (for-each (fn (el) (hs-activate! el)) elements)))) ;; ── Boot subtree: for dynamic content ─────────────────────────── ;; Called after HTMX swaps or dynamic DOM insertion. ;; Only activates elements within the given root. (define hs-boot-subtree! (fn (root) (let ((elements (dom-query-all root "[_]"))) (for-each (fn (el) (hs-activate! el)) elements)) (when (dom-get-attr root "_") (hs-activate! root))))