diff --git a/demo/sitetools/core.cljs b/demo/sitetools/core.cljs index 085c176..8186138 100644 --- a/demo/sitetools/core.cljs +++ b/demo/sitetools/core.cljs @@ -44,7 +44,7 @@ _ (assert (string? path))] (when-some [h history] (.setToken h x) - (r/next-tick #(set! js/document.body.scrollTop 0)) + (r/after-render #(set! js/document.body.scrollTop 0)) state) (recur state [:set-page x])))) diff --git a/src/reagent/core.cljs b/src/reagent/core.cljs index 2d7bc55..cc74999 100644 --- a/src/reagent/core.cljs +++ b/src/reagent/core.cljs @@ -309,9 +309,18 @@ another cursor) these cursors are equivalent: nil) (defn next-tick - "Run f using requestAnimationFrame or equivalent." + "Run f using requestAnimationFrame or equivalent. + + f will be called just before components are rendered." [f] - (batch/next-tick f)) + (batch/do-before-flush f)) + +(defn after-render + "Run f using requestAnimationFrame or equivalent. + + f will be called just after components are rendered." + [f] + (batch/do-after-render f)) (defn partial "Works just like clojure.core/partial, except that it is an IFn, and diff --git a/src/reagent/impl/batching.cljs b/src/reagent/impl/batching.cljs index 906eccf..0a1e8f2 100644 --- a/src/reagent/impl/batching.cljs +++ b/src/reagent/impl/batching.cljs @@ -39,36 +39,49 @@ (.! c :cljsIsDirty false) (.' c forceUpdate))))) -(defn run-funs [a] - (dotimes [i (alength a)] - ((aget a i)))) ;; Set from ratom.cljs (defonce ratom-flush identity) -(deftype RenderQueue [^:mutable queue ^:mutable ^boolean scheduled? - ^:mutable after-render] +(deftype RenderQueue [^:mutable ^boolean scheduled?] Object - (queue-render [this c] - (.push queue c) + (enqueue [this k f] + (assert (some? f)) + (when (nil? (aget this k)) + (aset this k (array))) + (.push (aget this k) f) (.schedule this)) - (add-after-render [_ f] - (.push after-render f)) + + (run-funs [this k] + (when-some [fs (aget this k)] + (aset this k nil) + (dotimes [i (alength fs)] + ((aget fs i))))) + (schedule [this] (when-not scheduled? (set! scheduled? true) (next-tick #(.run-queue this)))) - (run-queue [_] - (ratom-flush) - (let [q queue - aq after-render] - (set! queue (array)) - (set! after-render (array)) - (set! scheduled? false) - (run-queue q) - (run-funs aq)))) -(defonce render-queue (RenderQueue. (array) false (array))) + (queue-render [this c] + (.enqueue this "componentQueue" c)) + + (add-before-flush [this f] + (.enqueue this "beforeFlush" f)) + + (add-after-render [this f] + (.enqueue this "afterRender" f)) + + (run-queue [this] + (set! scheduled? false) + (.run-funs this "beforeFlush") + (ratom-flush) + (when-some [cs (aget this "componentQueue")] + (aset this "componentQueue" nil) + (run-queue cs)) + (.run-funs this "afterRender"))) + +(defonce render-queue (RenderQueue. false)) (defn flush [] (.run-queue render-queue)) @@ -80,12 +93,11 @@ (defn mark-rendered [c] (.! c :cljsIsDirty false)) -(defn do-after-flush [f] - (.add-after-render render-queue f)) +(defn do-before-flush [f] + (.add-before-flush render-queue f)) -(defn do-later [f] - (do-after-flush f) - (.schedule render-queue)) +(defn do-after-render [f] + (.add-after-render render-queue f)) (defn schedule [] (when (false? (.-scheduled? render-queue)) diff --git a/src/reagent/impl/template.cljs b/src/reagent/impl/template.cljs index 51cc2b6..78922c1 100644 --- a/src/reagent/impl/template.cljs +++ b/src/reagent/impl/template.cljs @@ -161,7 +161,7 @@ ;; wants to keep the value unchanged (when-not (.' this :cljsInputDirty) (.! this :cljsInputDirty true) - (batch/do-later #(input-set-value this))) + (batch/do-after-render #(input-set-value this))) res)) (defn input-render-setup [this jsprops]