A more complete Reagent config, including with-let
This commit is contained in:
parent
03f5f0b9a3
commit
c329a1a9d0
|
@ -1,15 +1,106 @@
|
||||||
(ns scittle.reagent
|
(ns scittle.reagent
|
||||||
(:require [reagent.core :as r]
|
(:require [reagent.core :as r]
|
||||||
|
[reagent.debug :as d :refer-macros [dev?]]
|
||||||
[reagent.dom :as rdom]
|
[reagent.dom :as rdom]
|
||||||
|
[reagent.ratom :as ratom]
|
||||||
[sci.core :as sci]
|
[sci.core :as sci]
|
||||||
[scittle.core :as scittle]))
|
[scittle.core :as scittle]))
|
||||||
|
|
||||||
|
;; The with-let macro from reagent.core. The only change is that the
|
||||||
|
;; interop/unchecked-aget+set were replaced by aget and aset.
|
||||||
|
(defn ^:macro with-let [_ _ bindings & body]
|
||||||
|
(assert (vector? bindings)
|
||||||
|
(str "with-let bindings must be a vector, not "
|
||||||
|
(pr-str bindings)))
|
||||||
|
(let [v (gensym "with-let")
|
||||||
|
k (keyword v)
|
||||||
|
init (gensym "init")
|
||||||
|
;; V is a reaction, which holds a JS array.
|
||||||
|
;; If the array is empty, initialize values and store to the
|
||||||
|
;; array, using binding index % 2 to access the array.
|
||||||
|
;; After init, the bindings are just bound to the values in the array.
|
||||||
|
bs (into [init `(zero? (alength ~v))]
|
||||||
|
(map-indexed (fn [i x]
|
||||||
|
(if (even? i)
|
||||||
|
x
|
||||||
|
(let [j (quot i 2)]
|
||||||
|
;; Issue 525
|
||||||
|
;; If binding value is not yet set,
|
||||||
|
;; try setting it again. This should
|
||||||
|
;; also throw errors for each render
|
||||||
|
;; and prevent the body being called
|
||||||
|
;; if bindings throw errors.
|
||||||
|
`(if (or ~init
|
||||||
|
(not (.hasOwnProperty ~v ~j)))
|
||||||
|
(aset ~v ~j ~x)
|
||||||
|
(aget ~v ~j)))))
|
||||||
|
bindings))
|
||||||
|
[forms destroy] (let [fin (last body)]
|
||||||
|
(if (and (list? fin)
|
||||||
|
(= 'finally (first fin)))
|
||||||
|
[(butlast body) `(fn [] ~@(rest fin))]
|
||||||
|
[body nil]))
|
||||||
|
add-destroy (when destroy
|
||||||
|
(list
|
||||||
|
`(let [destroy# ~destroy]
|
||||||
|
(if (reagent.ratom/reactive?)
|
||||||
|
(when (nil? (.-destroy ~v))
|
||||||
|
(set! (.-destroy ~v) destroy#))
|
||||||
|
(destroy#)))))
|
||||||
|
asserting (dev?) #_(if *assert* true false)
|
||||||
|
res (gensym "res")]
|
||||||
|
`(let [~v (reagent.ratom/with-let-values ~k)]
|
||||||
|
~(when asserting
|
||||||
|
`(when-some [c# (reagent.ratom/-ratom-context)]
|
||||||
|
(when (== (.-generation ~v) (.-ratomGeneration c#))
|
||||||
|
(d/error "Warning: The same with-let is being used more "
|
||||||
|
"than once in the same reactive context."))
|
||||||
|
(set! (.-generation ~v) (.-ratomGeneration c#))))
|
||||||
|
(let ~(into bs [res `(do ~@forms)])
|
||||||
|
~@add-destroy
|
||||||
|
~res))))
|
||||||
|
|
||||||
(def rns (sci/create-ns 'reagent.core nil))
|
(def rns (sci/create-ns 'reagent.core nil))
|
||||||
|
|
||||||
(def reagent-namespace
|
(def reagent-namespace
|
||||||
{'atom (sci/copy-var r/atom rns)
|
{'atom (sci/copy-var r/atom rns)
|
||||||
'as-element (sci/copy-var r/as-element rns)
|
'as-element (sci/copy-var r/as-element rns)
|
||||||
'create-class (sci/copy-var r/create-class rns)})
|
'with-let (sci/copy-var with-let rns)
|
||||||
|
'cursor (sci/copy-var r/cursor rns)
|
||||||
|
'create-class (sci/copy-var r/create-class rns)
|
||||||
|
'create-compiler (sci/copy-var r/create-compiler rns)})
|
||||||
|
|
||||||
|
(def rtmns (sci/create-ns 'reagent.ratom nil))
|
||||||
|
|
||||||
|
(defn -ratom-context
|
||||||
|
"Read-only access to the ratom context."
|
||||||
|
[]
|
||||||
|
ratom/*ratom-context*)
|
||||||
|
|
||||||
|
(def reagent-ratom-namespace
|
||||||
|
{'with-let-values (sci/copy-var ratom/with-let-values rtmns)
|
||||||
|
'reactive? (sci/copy-var ratom/reactive? rtmns)
|
||||||
|
'-ratom-context (sci/copy-var -ratom-context rtmns)})
|
||||||
|
|
||||||
|
(def rdbgns (sci/create-ns 'reagent.debug nil))
|
||||||
|
|
||||||
|
(defn -tracking? []
|
||||||
|
reagent.debug/tracking)
|
||||||
|
|
||||||
|
(defn ^:macro error
|
||||||
|
"Print with console.error."
|
||||||
|
[_ _ & forms]
|
||||||
|
(when *assert*
|
||||||
|
`(when (some? js/console)
|
||||||
|
(.error (if (reagent.debug/-tracking?)
|
||||||
|
reagent.debug/track-console
|
||||||
|
js/console)
|
||||||
|
(str ~@forms)))))
|
||||||
|
|
||||||
|
(def reagent-debug-namespace
|
||||||
|
{'error (sci/copy-var error rdbgns)
|
||||||
|
'-tracking? (sci/copy-var -tracking? rdbgns)
|
||||||
|
'track-console (sci/copy-var d/track-console rdbgns)})
|
||||||
|
|
||||||
(def rdns (sci/create-ns 'reagent.dom nil))
|
(def rdns (sci/create-ns 'reagent.dom nil))
|
||||||
|
|
||||||
|
@ -19,4 +110,6 @@
|
||||||
(scittle/register-plugin!
|
(scittle/register-plugin!
|
||||||
::reagent
|
::reagent
|
||||||
{:namespaces {'reagent.core reagent-namespace
|
{:namespaces {'reagent.core reagent-namespace
|
||||||
'reagent.dom reagent-dom-namespace}})
|
'reagent.dom reagent-dom-namespace
|
||||||
|
'reagent.ratom reagent-ratom-namespace
|
||||||
|
'reagent.debug reagent-debug-namespace}})
|
||||||
|
|
Loading…
Reference in a new issue