Use new javascript interop macros

This commit is contained in:
Dan Holmsand 2014-03-25 12:37:28 +01:00
parent 976cf8ef0b
commit 2e0e369d93
6 changed files with 90 additions and 91 deletions

View File

@ -7,7 +7,7 @@
[reagent.impl.batching :as batch]
[reagent.ratom :as ratom]
[reagent.debug :refer-macros [dbg prn]]
[reagent.interop :refer-macros [oset oget odo]]))
[reagent.interop :refer-macros [.' .!]]))
(def React util/React)
@ -40,7 +40,7 @@ Returns the mounted component instance."
(defn render-component-to-string
"Turns a component into an HTML string."
([component]
(odo React :renderComponentToString (as-component component))))
(.' React renderComponentToString (as-component component))))
(defn ^:export force-update-all []
(util/force-update-all))
@ -114,8 +114,7 @@ Everything is optional, except :render.
(defn dom-node
"Returns the root DOM node of a mounted component."
[this]
(odo this :getDOMNode))
(.' this getDOMNode))
(defn merge-props
"Utility function that merges two maps, handling :class and :style

View File

@ -1,7 +1,7 @@
(ns reagent.impl.batching
(:refer-clojure :exclude [flush])
(:require [reagent.debug :refer-macros [dbg]]
[reagent.interop :refer-macros [oget oset odo]]
[reagent.interop :refer-macros [.' .!]]
[reagent.ratom :as ratom]
[reagent.impl.util :refer [is-client]]
[clojure.string :as string]))
@ -15,15 +15,15 @@
(if-not is-client
fake-raf
(let [w js/window]
(or (oget w :requestAnimationFrame)
(oget w :webkitRequestAnimationFrame)
(oget w :mozRequestAnimationFrame)
(oget w :msRequestAnimationFrame)
(or (.' w :requestAnimationFrame)
(.' w :webkitRequestAnimationFrame)
(.' w :mozRequestAnimationFrame)
(.' w :msRequestAnimationFrame)
fake-raf))))
(defn compare-levels [c1 c2]
(- (oget c1 :props :level)
(oget c2 :props :level)))
(- (.' c1 :props.level)
(.' c2 :props.level)))
(defn run-queue [a]
;; sort components by level, to make sure parents
@ -31,8 +31,8 @@
(.sort a compare-levels)
(dotimes [i (alength a)]
(let [c (aget a i)]
(when (oget c :cljsIsDirty)
(odo c :forceUpdate)))))
(when (.' c :cljsIsDirty)
(.' c forceUpdate)))))
(deftype RenderQueue [^:mutable queue ^:mutable scheduled?]
Object
@ -55,34 +55,34 @@
(.run-queue render-queue))
(defn queue-render [c]
(oset c :cljsIsDirty true)
(.! c :cljsIsDirty true)
(.queue-render render-queue c))
(defn mark-rendered [c]
(oset c :cljsIsDirty false))
(.! c :cljsIsDirty false))
;; Render helper
(defn is-reagent-component [c]
(some-> c (oget :props) (oget :argv)))
(some-> c (.' :props) (.' :argv)))
(defn run-reactively [c run]
(assert (is-reagent-component c))
(mark-rendered c)
(let [rat (oget c :cljsRatom)]
(let [rat (.' c :cljsRatom)]
(if (nil? rat)
(let [res (ratom/capture-derefed run c)
derefed (ratom/captured c)]
(when (not (nil? derefed))
(oset c :cljsRatom
(ratom/make-reaction run
:auto-run #(queue-render c)
:derefed derefed)))
(.! c :cljsRatom
(ratom/make-reaction run
:auto-run #(queue-render c)
:derefed derefed)))
res)
(ratom/run rat))))
(defn dispose [c]
(some-> (oget c :cljsRatom)
(some-> (.' c :cljsRatom)
ratom/dispose!)
(mark-rendered c))

View File

@ -3,7 +3,7 @@
(:require [reagent.impl.util :as util :refer [React]]
[reagent.impl.batching :as batch]
[reagent.ratom :as ratom]
[reagent.interop :refer-macros [oget oset odo]]
[reagent.interop :refer-macros [.' .!]]
[reagent.debug :refer-macros [dbg prn]]))
(declare ^:dynamic *current-component*)
@ -11,10 +11,10 @@
;;; State
(defn state-atom [this]
(let [sa (oget this :cljsState)]
(let [sa (.' this :cljsState)]
(if-not (nil? sa)
sa
(oset this :cljsState (ratom/atom nil)))))
(.! this :cljsState (ratom/atom nil)))))
(defn state [this]
(deref (state-atom this)))
@ -32,12 +32,12 @@
(defn do-render [c]
(binding [*current-component* c]
(let [f (oget c :cljsRender)
(let [f (.' c :cljsRender)
_ (assert (util/clj-ifn? f))
p (oget c :props)
res (if (nil? (oget c :componentFunction))
p (.' c :props)
res (if (nil? (.' c :componentFunction))
(f c)
(let [argv (oget p :argv)
(let [argv (.' p :argv)
n (count argv)]
(case n
1 (f)
@ -47,10 +47,10 @@
5 (f (nth argv 1) (nth argv 2) (nth argv 3) (nth argv 4))
(apply f (subvec argv 1)))))]
(if (vector? res)
(odo c :asComponent res (oget p :level))
(.' c asComponent res (.' p :level))
(if (ifn? res)
(do
(oset c :cljsRender res)
(.! c :cljsRender res)
(do-render c))
res)))))
@ -70,7 +70,7 @@
:componentWillReceiveProps
(fn [props]
(this-as c
(f c (oget props :argv))))
(f c (.' props :argv))))
:shouldComponentUpdate
(fn [nextprops nextstate]
@ -78,8 +78,8 @@
(this-as c
;; Don't care about nextstate here, we use forceUpdate
;; when only when state has changed anyway.
(let [old-argv (oget c :props :argv)
new-argv (oget nextprops :argv)]
(let [old-argv (.' c :props.argv)
new-argv (.' nextprops :argv)]
(if (nil? f)
(not (util/equal-args old-argv new-argv))
(f c old-argv new-argv))))))
@ -87,12 +87,12 @@
:componentWillUpdate
(fn [nextprops]
(this-as c
(f c (oget nextprops :argv))))
(f c (.' nextprops :argv))))
:componentDidUpdate
(fn [oldprops]
(this-as c
(f c (oget oldprops :argv))))
(f c (.' oldprops :argv))))
:componentWillUnmount
(fn []
@ -114,7 +114,7 @@
(defn dont-bind [f]
(if (ifn? f)
(doto f
(oset :__reactDontBind true))
(.! :__reactDontBind true))
f))
(defn get-wrapper [key f name]
@ -155,8 +155,8 @@
(str "Render must be a function, not "
(pr-str render-fun)))
name (or (:displayName fun-map)
(oget render-fun :displayName)
(oget render-fun :name))
(.' render-fun :displayName)
(.' render-fun :name))
name' (if (empty? name) (str (gensym "reagent")) name)
fmap (-> fun-map
(assoc :displayName name')
@ -182,8 +182,8 @@
[body as-component]
(assert (map? body))
(let [spec (cljsify body)
_ (oset spec :asComponent (dont-bind as-component))
res (odo React :createClass spec)
_ (.! spec :asComponent (dont-bind as-component))
res (.' React createClass spec)
f (fn [& args]
(as-component (apply vector res args)))]
(util/cache-react-class f res)

View File

@ -5,7 +5,7 @@
[reagent.impl.component :as comp]
[reagent.impl.batching :as batch]
[reagent.ratom :as ratom]
[reagent.interop :refer-macros [oget oset odo]]
[reagent.interop :refer-macros [.' .!]]
[reagent.debug :refer-macros [dbg prn println log dev?]]))
;; From Weavejester's Hiccup, via pump:
@ -13,7 +13,7 @@
from a tag name."}
re-tag #"([^\s\.#]+)(?:#([^\s\.#]+))?(?:\.([^\s#]+))?")
(def DOM (oget React :DOM))
(def DOM (.' React :DOM))
(def attr-aliases {:class "className"
:for "htmlFor"
@ -62,11 +62,11 @@
:else (to-js-val x)))
(defn set-id-class [props [id class]]
(let [pid (oget props :id)]
(oset props :id (if-not (nil? pid) pid id))
(let [pid (.' props :id)]
(.! props :id (if-not (nil? pid) pid id))
(when-not (nil? class)
(let [old (oget props :className)]
(oset props :className (if-not (nil? old)
(let [old (.' props :className)]
(.! props :className (if-not (nil? old)
(str class " " old)
class))))))
@ -97,28 +97,28 @@
res))
(defn input-did-update [this]
(let [value (oget this :cljsInputValue)]
(let [value (.' this :cljsInputValue)]
(when-not (nil? value)
(let [node (odo this :getDOMNode)]
(when (not= value (oget node :value))
(oset node :value value))))))
(let [node (.' this getDOMNode)]
(when (not= value (.' node :value))
(.! node :value value))))))
(defn input-render-setup [this jsprops]
;; Don't rely on React for updating "controlled inputs", since it
;; doesn't play well with async rendering (misses keystrokes).
(let [on-change (oget jsprops :onChange)
(let [on-change (.' jsprops :onChange)
value (when-not (nil? on-change)
(oget jsprops :value))]
(oset this :cljsInputValue value)
(.' jsprops :value))]
(.! this :cljsInputValue value)
(when-not (nil? value)
(batch/mark-rendered this)
(doto jsprops
(oset :defaultValue value)
(oset :value nil)
(oset :onChange #(input-handle-change this on-change %))))))
(.! :defaultValue value)
(.! :value nil)
(.! :onChange #(input-handle-change this on-change %))))))
(def input-components #{(oget DOM :input)
(oget DOM :textarea)})
(def input-components #{(.' DOM :input)
(.' DOM :textarea)})
;;; Wrapping of native components
@ -126,13 +126,13 @@
(declare convert-args)
(defn wrapped-render [this comp id-class input-setup]
(let [inprops (oget this :props)
argv (oget inprops :argv)
(let [inprops (.' this :props)
argv (.' inprops :argv)
props (nth argv 1 nil)
hasprops (or (nil? props) (map? props))
jsargs (convert-args argv
(if hasprops 2 1)
(inc (oget inprops :level)))
(inc (.' inprops :level)))
jsprops (convert-props (if hasprops props) id-class)]
(when-not (nil? input-setup)
(input-setup this jsprops))
@ -141,14 +141,14 @@
(defn wrapped-should-update [c nextprops nextstate]
(or util/*always-update*
(let [a1 (oget c :props :argv)
a2 (oget nextprops :argv)]
(let [a1 (.' c :props.argv)
a2 (.' nextprops :argv)]
(not (util/equal-args a1 a2)))))
(defn add-input-methods [spec]
(doto spec
(oset :componentDidUpdate #(this-as c (input-did-update c)))
(oset :componentWillUnmount #(this-as c (batch/dispose c)))))
(.! :componentDidUpdate #(this-as c (input-did-update c)))
(.! :componentWillUnmount #(this-as c (batch/dispose c)))))
(defn wrap-component [comp extras name]
(let [input? (input-components comp)
@ -160,7 +160,7 @@
:displayName (or name "ComponentWrapper")}]
(when input?
(add-input-methods spec))
(odo React :createClass spec)))
(.' React createClass spec)))
;;; Conversion from Hiccup forms
@ -197,7 +197,7 @@
(let [cached-class (util/cached-react-class tag)]
(if-not (nil? cached-class)
cached-class
(if (odo React :isValidClass tag)
(if (.' React isValidClass tag)
(util/cache-react-class tag (wrap-component tag nil nil))
(fn-to-class tag)))))))
@ -216,16 +216,16 @@
(-> v (nth 1 nil) get-key)
k)]
(when-not (nil? k')
(oset jsprops :key k')))
(.! jsprops :key k')))
(c jsprops)))
(def seq-ctx #js{})
(defn warn-on-deref [x]
(when-not (oget seq-ctx :warned)
(when-not (.' seq-ctx :warned)
(log "Warning: Reactive deref not supported in seq in "
(pr-str x))
(oset seq-ctx :warned true)))
(.! seq-ctx :warned true)))
(declare expand-seq)

View File

@ -1,10 +1,10 @@
(ns reagent.impl.util
(:require [reagent.debug :refer-macros [dbg log]]
[reagent.interop :refer-macros [oget oset odo]]
[reagent.interop :refer-macros [.' .!]]
[clojure.string :as string]))
(def is-client (and (exists? js/window)
(-> js/window (oget :document) nil? not)))
(-> js/window (.' :document) nil? not)))
(def React js/React)
@ -21,22 +21,22 @@
(subvec v first-child))))
(defn get-argv [c]
(oget c :props :argv))
(.' c :props.argv))
(defn get-props [c]
(-> (oget c :props :argv) extract-props))
(-> (.' c :props.argv) extract-props))
(defn get-children [c]
(-> (oget c :props :argv) extract-children))
(-> (.' c :props.argv) extract-children))
(defn reagent-component? [c]
(-> (oget c :props :argv) nil? not))
(-> (.' c :props.argv) nil? not))
(defn cached-react-class [c]
(oget c :cljsReactClass))
(.' c :cljsReactClass))
(defn cache-react-class [c constructor]
(oset c :cljsReactClass constructor))
(.! c :cljsReactClass constructor))
;; Misc utilities
@ -116,32 +116,32 @@
(defn get-react-node [cont]
(when-not (nil? cont)
(if (== doc-node-type (oget cont :nodeType))
(oget cont :documentElement)
(oget cont :firstChild))))
(if (== doc-node-type (.' cont :nodeType))
(.' cont :documentElement)
(.' cont :firstChild))))
(defn get-root-id [cont]
(some-> (get-react-node cont)
(odo :getAttribute react-id-name)))
(.' getAttribute react-id-name)))
(def roots (atom {}))
(defn re-render-component [comp container]
(try
(odo React :renderComponent (comp) container)
(.' React renderComponent (comp) container)
(catch js/Object e
(do
(try
(odo React :unmountComponentAtNode container)
(.' React unmountComponentAtNode container)
(catch js/Object e
(log e)))
(when-let [n (get-react-node container)]
(odo n :removeAttribute react-id-name)
(oset n :innerHTML ""))
(.' n removeAttribute react-id-name)
(.! n :innerHTML ""))
(throw e)))))
(defn render-component [comp container callback]
(odo React :renderComponent (comp) container
(.' React renderComponent (comp) container
(fn []
(let [id (get-root-id container)]
(when-not (nil? id)
@ -154,7 +154,7 @@
(let [id (get-root-id container)]
(when-not (nil? id)
(swap! roots dissoc id)))
(odo React :unmountComponentAtNode container))
(.' React unmountComponentAtNode container))
(defn force-update-all []
(binding [*always-update* true]

View File

@ -1,7 +1,7 @@
(ns runtests
(:require [reagent.core :as reagent :refer [atom]]
[reagent.interop :refer-macros [oget oset odo]]
[reagent.interop :refer-macros [.' .!]]
[reagent.debug :refer-macros [dbg println]]
[demo :as demo]
[cemerick.cljs.test :as t]))