mirror of https://github.com/status-im/reagent.git
Add macros for more convenient javascript interop
This commit is contained in:
parent
23ae1661fe
commit
8b59d1509b
|
@ -0,0 +1,40 @@
|
||||||
|
(ns reagent.interop)
|
||||||
|
|
||||||
|
(defn- js-call [f args]
|
||||||
|
(let [argstr (->> (repeat (count args) "~{}")
|
||||||
|
(interpose ",")
|
||||||
|
(apply str))]
|
||||||
|
(list* 'js* (str "~{}(" argstr ")") f args)))
|
||||||
|
|
||||||
|
(defn- from-keyword [k]
|
||||||
|
(if (keyword? k)
|
||||||
|
(name k)
|
||||||
|
k))
|
||||||
|
|
||||||
|
(defn- get-names [k]
|
||||||
|
(->> (if (vector? k) k [k])
|
||||||
|
(map from-keyword)))
|
||||||
|
|
||||||
|
(defmacro jget
|
||||||
|
[o k]
|
||||||
|
`(aget ~o ~@(get-names k)))
|
||||||
|
|
||||||
|
(defmacro jset
|
||||||
|
[o k v]
|
||||||
|
`(aset ~o ~@(get-names k) ~v))
|
||||||
|
|
||||||
|
(defmacro jcall
|
||||||
|
[o k & args]
|
||||||
|
(let [names (get-names k)
|
||||||
|
f (if (empty? names)
|
||||||
|
o
|
||||||
|
(list* 'aget o names))]
|
||||||
|
(js-call f args)))
|
||||||
|
|
||||||
|
(defmacro jval
|
||||||
|
[s]
|
||||||
|
(assert (keyword? s))
|
||||||
|
(let [sym (symbol "js" (name s))]
|
||||||
|
`(when (clojure.core/exists? ~sym)
|
||||||
|
~sym)))
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
(ns reagent.interop)
|
||||||
|
|
||||||
|
;; Empty file, to allow require with :refer-macros
|
|
@ -0,0 +1,49 @@
|
||||||
|
(ns testinterop
|
||||||
|
(:require [cemerick.cljs.test :as t :refer-macros [is deftest]]
|
||||||
|
[reagent.debug :refer-macros [dbg]]
|
||||||
|
[reagent.interop :refer-macros [jget jset jcall jval]]))
|
||||||
|
|
||||||
|
(deftest interop-basic
|
||||||
|
(let [o #js {:foo "foo"
|
||||||
|
:foobar #js {:bar "bar"}}]
|
||||||
|
(is (= "foo" (jget o :foo)))
|
||||||
|
(is (= "foo" (jget o [:foo])))
|
||||||
|
(is (= "bar" (jget o [:foobar :bar])))
|
||||||
|
|
||||||
|
(jset o :foo "foo1")
|
||||||
|
(is (= "foo1" (jget o :foo)))
|
||||||
|
|
||||||
|
(jset o [:foo] "foo2")
|
||||||
|
(is (= "foo2" (jget o :foo)))
|
||||||
|
|
||||||
|
(jset o [:foobar :bar] "bar1")
|
||||||
|
(is (= "bar1" (jget o [:foobar :bar])))))
|
||||||
|
|
||||||
|
(deftest interop-call
|
||||||
|
(let [o #js {:bar "bar1"
|
||||||
|
:foo (fn [x]
|
||||||
|
(this-as this
|
||||||
|
(str x (jget this :bar))))}
|
||||||
|
o2 #js {:o o}]
|
||||||
|
(is (= "ybar1" (jcall o :foo "y")))
|
||||||
|
(is (= "xxbar1" (jcall o2 [:o :foo] "xx")))
|
||||||
|
(is (= "abar1" (-> o2
|
||||||
|
(jget [:o :foo])
|
||||||
|
(jcall [] "a"))))
|
||||||
|
|
||||||
|
(is (= "bar1" (jcall o :foo)))
|
||||||
|
(is (= "bar1" (jcall o [:foo])))
|
||||||
|
(is (= "bar1" (jcall o2 [:o :foo])))
|
||||||
|
|
||||||
|
(jset o :bar "bar2")
|
||||||
|
(is (= "bar2" (jcall o :foo)))
|
||||||
|
|
||||||
|
(is (= "1bar2" (jcall (jget o :foo)
|
||||||
|
:call o 1)))
|
||||||
|
|
||||||
|
(is (= "yy" (jcall identity [] "yy")))))
|
||||||
|
|
||||||
|
(deftest interop-val
|
||||||
|
(set! js/someGlobal "foo")
|
||||||
|
(is (= "foo" (jval :someGlobal)))
|
||||||
|
(is (nil? (jval :nonExistingGlobal))))
|
Loading…
Reference in New Issue