Skip to content

Commit c51814a

Browse files
committed
dom/Await-element now re-attaches when target goes away and comes back
1 parent 84f3902 commit c51814a

File tree

1 file changed

+23
-18
lines changed

1 file changed

+23
-18
lines changed

src/hyperfiddle/electric_dom3.cljc

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -592,30 +592,35 @@ input's value, use `EventListener`."
592592
(defmacro video [& body] (element* :video body))
593593
(defmacro wbr [& body] (element* :wbr body))
594594

595-
#?(:cljs (defn await-element [node selector]
595+
#?(:cljs (defn await-element-first-match-only [node selector]
596596
(fn [s f]
597597
(let [o (js/MutationObserver.
598598
(fn [ms o]
599-
(try (when-let [x (.querySelector js/document selector)] ; todo optimize
600-
#(.disconnect o) (s x)) (catch :default e (f e)))))]
599+
(try
600+
(when-let [x (.querySelector node selector)]
601+
#(.disconnect o) ; stop listening after first detection
602+
(s x))
603+
(catch :default e (f e)))))]
601604
(try (.observe o node #js{:subtree true :childList true})
602-
(catch :default e (f e)))))))
605+
(catch :default e (f e)))
606+
#(.disconnect o)))))
603607

604-
(e/defn Await-element [node selector]
605-
; this is expensive, so don't provide the js/document.body default
606-
(e/Task (await-element node selector)))
607-
608-
#?(:cljs (defn await-elements [node selector]
608+
#?(:cljs (defn await-element "
609+
return flow of elements matching selector over time, i.e. as the target element comes and goes
610+
we need to keep listening for when it comes back"
611+
[node selector]
609612
(m/observe
610613
(fn [!]
611614
(let [o (js/MutationObserver.
612615
(fn [ms o]
613-
(doseq [x (array-seq (.querySelectorAll js/document selector))]
614-
#_(prn 'mut selector x)
615-
(! x))
616-
#_(try (catch :default e (f e)))))]
617-
(.observe o node #js{:subtree true :childList true})
618-
#_(try (catch :default e (f e))))))))
619-
620-
(e/defn Await-elements [node selector]
621-
(e/client (e/join (e/flow->incseq (await-elements node selector)))))
616+
(when-let [x (.querySelector node selector)]
617+
#_(prn 'mut selector x) (! x))
618+
; todo use querySelectorAll and return simultaneous matches as table
619+
#_(doseq [x (array-seq (.querySelectorAll node selector))] (! x))))]
620+
(try (.observe o node #js{:subtree true :childList true})
621+
(catch :default e (js/error "MutationObserver failed, invalid call? e: " e)))
622+
#(.disconnect o))))))
623+
624+
(e/defn Await-element [node selector] ; reactive to elements coming and going
625+
; this is expensive, so don't provide the js/document.body default node
626+
(e/client (e/input (await-element node selector))))

0 commit comments

Comments
 (0)