Make next-tick more predictable, add after-render

This commit is contained in:
Dan Holmsand 2015-10-11 22:08:42 +02:00
parent edf001cb62
commit 78fffe263e
4 changed files with 49 additions and 28 deletions

View File

@ -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]))))

View File

@ -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

View File

@ -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))

View File

@ -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]