support exposing clojure functions to rhino
This commit is contained in:
parent
3e8419f935
commit
2fc12781ef
17
README.rest
17
README.rest
|
@ -81,6 +81,23 @@ handy convertions::
|
||||||
user=> (js/from-js (js/eval sc "o = {name: 'spongebob', friends: ['patrick', 'sandy']};"))
|
user=> (js/from-js (js/eval sc "o = {name: 'spongebob', friends: ['patrick', 'sandy']};"))
|
||||||
{:friends ["patrick" "sandy"], :name "spongebob"}
|
{:friends ["patrick" "sandy"], :name "spongebob"}
|
||||||
|
|
||||||
|
exposing clojure functions to rhino::
|
||||||
|
|
||||||
|
user=> (require '[clj-rhino :as js])
|
||||||
|
nil
|
||||||
|
|
||||||
|
user=> (defn add [ctx scope this [a b]] (+ a b))
|
||||||
|
#'user/add
|
||||||
|
|
||||||
|
user=> (def scope (js/new-safe-scope))
|
||||||
|
#'user/scope
|
||||||
|
|
||||||
|
user=> (js/set! scope "add" (js/make-fn add))
|
||||||
|
nil
|
||||||
|
|
||||||
|
user=> (js/eval scope "add(1, 2)")
|
||||||
|
3.0
|
||||||
|
|
||||||
license?
|
license?
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns clj-rhino
|
(ns clj-rhino
|
||||||
(:refer-clojure :exclude (eval get get-in set!))
|
(:refer-clojure :exclude (eval get get-in set!))
|
||||||
(:import [org.mozilla.javascript Context UniqueTag NativeArray NativeObject]))
|
(:import [org.mozilla.javascript Context UniqueTag NativeArray NativeObject
|
||||||
|
BaseFunction]))
|
||||||
|
|
||||||
(defprotocol RhinoConvertible
|
(defprotocol RhinoConvertible
|
||||||
(-to-rhino [object scope ctx] "convert a value to a rhino compatible type"))
|
(-to-rhino [object scope ctx] "convert a value to a rhino compatible type"))
|
||||||
|
@ -198,3 +199,13 @@
|
||||||
(.compileFunction ctx scope code
|
(.compileFunction ctx scope code
|
||||||
(or filename "<eval>")
|
(or filename "<eval>")
|
||||||
(or line-number 1) sec-domain))))
|
(or line-number 1) sec-domain))))
|
||||||
|
|
||||||
|
(defn make-fn [fun]
|
||||||
|
"return an object that can be used as a function in rhino,
|
||||||
|
fun must receive the following arguments [ctx scope this args]
|
||||||
|
args will be passed through from-js before calling fun and the result
|
||||||
|
through to-js"
|
||||||
|
|
||||||
|
(proxy [BaseFunction] []
|
||||||
|
(call [ctx scope this args]
|
||||||
|
(to-js (fun ctx scope this (from-js args)) scope ctx))))
|
||||||
|
|
|
@ -80,7 +80,8 @@
|
||||||
(is (= (js/get scope "b") false))))
|
(is (= (js/get scope "b") false))))
|
||||||
|
|
||||||
(testing "to-js works"
|
(testing "to-js works"
|
||||||
(js/with-context (fn [ctx]
|
(js/with-context
|
||||||
|
(fn [ctx]
|
||||||
(let [scope (js/new-safe-scope)]
|
(let [scope (js/new-safe-scope)]
|
||||||
|
|
||||||
(is (= (js/to-js nil scope ctx) nil))
|
(is (= (js/to-js nil scope ctx) nil))
|
||||||
|
@ -101,7 +102,8 @@
|
||||||
(is (= (get (js/to-js {:name "mariano" :age 27} scope ctx) "age") 27))))))
|
(is (= (get (js/to-js {:name "mariano" :age 27} scope ctx) "age") 27))))))
|
||||||
|
|
||||||
(testing "to-js works on complex nested structures"
|
(testing "to-js works on complex nested structures"
|
||||||
(js/with-context (fn [ctx]
|
(js/with-context
|
||||||
|
(fn [ctx]
|
||||||
(let [scope (js/new-safe-scope)
|
(let [scope (js/new-safe-scope)
|
||||||
obj {:name "bob"
|
obj {:name "bob"
|
||||||
:age 27
|
:age 27
|
||||||
|
@ -117,7 +119,8 @@
|
||||||
(is (= (get-in js-obj ["friends" "sandy"]) "squirrel"))))))
|
(is (= (get-in js-obj ["friends" "sandy"]) "squirrel"))))))
|
||||||
|
|
||||||
(testing "unknown types throw exception when converting to-js"
|
(testing "unknown types throw exception when converting to-js"
|
||||||
(js/with-context (fn [ctx]
|
(js/with-context
|
||||||
|
(fn [ctx]
|
||||||
(let [scope (js/new-safe-scope)]
|
(let [scope (js/new-safe-scope)]
|
||||||
(is (thrown? Exception (js/to-js (atom {}) scope ctx)))))))
|
(is (thrown? Exception (js/to-js (atom {}) scope ctx)))))))
|
||||||
|
|
||||||
|
@ -154,5 +157,13 @@
|
||||||
(assert-simetric-convertion {:b {"c" {:d [{"e" 4}]}}} scope ctx
|
(assert-simetric-convertion {:b {"c" {:d [{"e" 4}]}}} scope ctx
|
||||||
{:b {:c {:d [{:e 4}]}}})
|
{:b {:c {:d [{:e 4}]}}})
|
||||||
))))
|
))))
|
||||||
)
|
|
||||||
|
(testing "native clojure functions can be added"
|
||||||
|
(js/with-context
|
||||||
|
(fn [ctx]
|
||||||
|
(let [scope (js/new-safe-scope)]
|
||||||
|
(js/set! scope "add" (js/make-fn (fn [ctx scope this [a b]] (+ a b))))
|
||||||
|
(is (= (js/eval scope "add(1, 2)") 3.0))))))
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
Reference in a new issue