More usage of interop macros

This commit is contained in:
Dan Holmsand 2014-03-14 12:28:10 +01:00
parent e21e58e509
commit 58dd46f4ae
5 changed files with 56 additions and 70 deletions

View File

@ -1,5 +1,5 @@
(defproject reagent "0.4.2" (defproject reagent "0.4.3-SNAPSHOT"
:url "http://github.com/holmsand/reagent" :url "http://github.com/holmsand/reagent"
:license {:name "MIT"} :license {:name "MIT"}
:description "A simple ClojureScript interface to React" :description "A simple ClojureScript interface to React"

View File

@ -3,7 +3,7 @@
(:require [reagent.debug :refer-macros [dbg log]] (:require [reagent.debug :refer-macros [dbg log]]
[reagent.interop :refer-macros [get. set. call.]] [reagent.interop :refer-macros [get. set. call.]]
[reagent.ratom :as ratom] [reagent.ratom :as ratom]
[reagent.impl.util :refer [cljs-level is-client]] [reagent.impl.util :refer [is-client]]
[clojure.string :as string])) [clojure.string :as string]))
;;; Update batching ;;; Update batching

View File

@ -1,22 +1,20 @@
(ns reagent.impl.component (ns reagent.impl.component
(:require [reagent.impl.util :as util :refer [cljs-level cljs-argv React]] (:require [reagent.impl.util :as util :refer [React]]
[reagent.impl.batching :as batch] [reagent.impl.batching :as batch]
[reagent.ratom :as ratom] [reagent.ratom :as ratom]
[reagent.interop :refer-macros [get. set. call.]]
[reagent.debug :refer-macros [dbg prn]])) [reagent.debug :refer-macros [dbg prn]]))
(declare ^:dynamic *current-component*) (declare ^:dynamic *current-component*)
(def cljs-state "cljsState")
(def cljs-render "cljsRender")
;;; State ;;; State
(defn state-atom [this] (defn state-atom [this]
(let [sa (aget this cljs-state)] (let [sa (get. this :cljsState)]
(if-not (nil? sa) (if-not (nil? sa)
sa sa
(aset this cljs-state (ratom/atom nil))))) (set. this :cljsState (ratom/atom nil)))))
(defn state [this] (defn state [this]
(deref (state-atom this))) (deref (state-atom this)))
@ -32,14 +30,14 @@
;;; Rendering ;;; Rendering
(defn do-render [C] (defn do-render [c]
(binding [*current-component* C] (binding [*current-component* c]
(let [f (aget C cljs-render) (let [f (get. c :cljsRender)
_ (assert (util/clj-ifn? f)) _ (assert (util/clj-ifn? f))
p (util/js-props C) p (get. c :props)
res (if (nil? (aget C "componentFunction")) res (if (nil? (get. c :componentFunction))
(f C) (f c)
(let [argv (aget p cljs-argv) (let [argv (get. p :argv)
n (count argv)] n (count argv)]
(case n (case n
1 (f) 1 (f)
@ -49,11 +47,11 @@
5 (f (nth argv 1) (nth argv 2) (nth argv 3) (nth argv 4)) 5 (f (nth argv 1) (nth argv 2) (nth argv 3) (nth argv 4))
(apply f (subvec argv 1)))))] (apply f (subvec argv 1)))))]
(if (vector? res) (if (vector? res)
(.asComponent C res (aget p cljs-level)) (call. c :asComponent res (get. p :level))
(if (ifn? res) (if (ifn? res)
(do (do
(aset C cljs-render res) (set. c :cljsRender res)
(do-render C)) (do-render c))
res))))) res)))))
@ -66,51 +64,48 @@
:getInitialState :getInitialState
(fn [] (fn []
(this-as C (this-as c
(set-state C (f C)))) (set-state c (f c))))
:componentWillReceiveProps :componentWillReceiveProps
(fn [props] (fn [props]
(this-as C (this-as c
(f C (aget props cljs-argv)))) (f c (get. props :argv))))
:shouldComponentUpdate :shouldComponentUpdate
(fn [nextprops nextstate] (fn [nextprops nextstate]
(this-as C (this-as c
;; Don't care about nextstate here, we use forceUpdate ;; Don't care about nextstate here, we use forceUpdate
;; when only when state has changed anyway. ;; when only when state has changed anyway.
(let [inprops (util/js-props C) (let [old-argv (get. c [:props :argv])
old-argv (aget inprops cljs-argv) new-argv (get. nextprops :argv)]
new-argv (aget nextprops cljs-argv)]
(if (nil? f) (if (nil? f)
(not (util/equal-args old-argv new-argv)) (not (util/equal-args old-argv new-argv))
(f C old-argv new-argv))))) (f c old-argv new-argv)))))
:componentWillUpdate :componentWillUpdate
(fn [nextprops] (fn [nextprops]
(this-as C (this-as c
(let [next-argv (aget nextprops cljs-argv)] (f c (get. nextprops :argv))))
(f C next-argv))))
:componentDidUpdate :componentDidUpdate
(fn [oldprops] (fn [oldprops]
(this-as C (this-as c
(let [old-argv (aget oldprops cljs-argv)] (f c (get. oldprops :argv))))
(f C old-argv))))
:componentWillUnmount :componentWillUnmount
(fn [] (fn []
(this-as C (this-as c
(batch/dispose C) (batch/dispose c)
(when-not (nil? f) (when-not (nil? f)
(f C)))) (f c))))
nil)) nil))
(defn default-wrapper [f] (defn default-wrapper [f]
(if (ifn? f) (if (ifn? f)
(fn [& args] (fn [& args]
(this-as C (apply f C args))) (this-as c (apply f c args)))
f)) f))
(def dont-wrap #{:cljsRender :render :componentFunction}) (def dont-wrap #{:cljsRender :render :componentFunction})
@ -148,9 +143,9 @@
:cljsRender render-f :cljsRender render-f
:render (if util/is-client :render (if util/is-client
(fn [] (fn []
(this-as C (this-as c
(batch/run-reactively C #(do-render C)))) (batch/run-reactively c #(do-render c))))
(fn [] (this-as C (do-render C)))))) (fn [] (this-as c (do-render c))))))
(defn wrap-funs [fun-map] (defn wrap-funs [fun-map]
(let [render-fun (or (:componentFunction fun-map) (let [render-fun (or (:componentFunction fun-map)
@ -159,8 +154,8 @@
(str "Render must be a function, not " (str "Render must be a function, not "
(pr-str render-fun))) (pr-str render-fun)))
name (or (:displayName fun-map) name (or (:displayName fun-map)
(.-displayName render-fun) (get. render-fun :displayName)
(.-name render-fun)) (get. render-fun :name))
name' (if (empty? name) (str (gensym "reagent")) name) name' (if (empty? name) (str (gensym "reagent")) name)
fmap (-> fun-map fmap (-> fun-map
(assoc :displayName name') (assoc :displayName name')
@ -186,8 +181,8 @@
[body as-component] [body as-component]
(assert (map? body)) (assert (map? body))
(let [spec (cljsify body) (let [spec (cljsify body)
_ (set! (.-asComponent spec) (dont-bind as-component)) _ (set. spec :asComponent (dont-bind as-component))
res (.createClass React spec) res (call. React :createClass spec)
f (fn [& args] f (fn [& args]
(as-component (apply vector res args)))] (as-component (apply vector res args)))]
(set! (.-cljsReactClass f) res) (set! (.-cljsReactClass f) res)

View File

@ -1,8 +1,7 @@
(ns reagent.impl.template (ns reagent.impl.template
(:require [clojure.string :as string] (:require [clojure.string :as string]
[reagent.impl.util :as util [reagent.impl.util :as util :refer [is-client React]]
:refer [cljs-level cljs-argv is-client React]]
[reagent.impl.component :as comp] [reagent.impl.component :as comp]
[reagent.impl.batching :as batch] [reagent.impl.batching :as batch]
[reagent.ratom :as ratom] [reagent.ratom :as ratom]
@ -124,7 +123,7 @@
(declare convert-args) (declare convert-args)
(defn wrapped-render [this comp id-class input-setup] (defn wrapped-render [this comp id-class input-setup]
(let [inprops (util/js-props this) (let [inprops (get. this :props)
argv (get. inprops :argv) argv (get. inprops :argv)
props (nth argv 1 nil) props (nth argv 1 nil)
hasprops (or (nil? props) (map? props)) hasprops (or (nil? props) (map? props))
@ -137,16 +136,15 @@
(aset jsargs 0 jsprops) (aset jsargs 0 jsprops)
(.apply comp nil jsargs))) (.apply comp nil jsargs)))
(defn wrapped-should-update [C nextprops nextstate] (defn wrapped-should-update [c nextprops nextstate]
(let [inprops (util/js-props C) (let [a1 (get. c [:props :argv])
a1 (get. inprops :argv)
a2 (get. nextprops :argv)] a2 (get. nextprops :argv)]
(not (util/equal-args a1 a2)))) (not (util/equal-args a1 a2))))
(defn add-input-methods [spec] (defn add-input-methods [spec]
(doto spec (doto spec
(set. :componentDidUpdate #(this-as C (input-did-update C))) (set. :componentDidUpdate #(this-as c (input-did-update c)))
(set. :componentWillUnmount #(this-as C (batch/dispose C))))) (set. :componentWillUnmount #(this-as c (batch/dispose c)))))
(defn wrap-component [comp extras name] (defn wrap-component [comp extras name]
(let [input? (input-components comp) (let [input? (input-components comp)
@ -207,14 +205,14 @@
(assert (valid-tag? (nth v 0)) (assert (valid-tag? (nth v 0))
(str "Invalid Hiccup form: " (pr-str v))) (str "Invalid Hiccup form: " (pr-str v)))
(let [c (as-class (nth v 0)) (let [c (as-class (nth v 0))
jsprops (js-obj cljs-argv v jsprops #js {:argv v
cljs-level level)] :level level}]
(let [k (-> v meta get-key) (let [k (-> v meta get-key)
k' (if (nil? k) k' (if (nil? k)
(-> v (nth 1 nil) get-key) (-> v (nth 1 nil) get-key)
k)] k)]
(when-not (nil? k') (when-not (nil? k')
(aset jsprops "key" k'))) (set. jsprops :key k')))
(c jsprops))) (c jsprops)))
(def tmp #js {}) (def tmp #js {})

View File

@ -11,13 +11,6 @@
;;; Props accessors ;;; Props accessors
(def props "props")
(def cljs-level "level")
(def cljs-argv "argv")
(defn js-props [C]
(get. C :props))
(defn extract-props [v] (defn extract-props [v]
(let [p (nth v 1 nil)] (let [p (nth v 1 nil)]
(if (map? p) p))) (if (map? p) p)))
@ -28,17 +21,17 @@
(if (> (count v) first-child) (if (> (count v) first-child)
(subvec v first-child)))) (subvec v first-child))))
(defn get-argv [C] (defn get-argv [c]
(get. C [:props :argv])) (get. c [:props :argv]))
(defn get-props [C] (defn get-props [c]
(-> (get. C [:props :argv]) extract-props)) (-> (get. c [:props :argv]) extract-props))
(defn get-children [C] (defn get-children [c]
(-> (get. C [:props :argv]) extract-children)) (-> (get. c [:props :argv]) extract-children))
(defn reagent-component? [C] (defn reagent-component? [c]
(-> (get. C [:props :argv]) nil? not)) (-> (get. c [:props :argv]) nil? not))
;; Misc utilities ;; Misc utilities