convert clojure functions to rhino functions in to-js

This commit is contained in:
Mariano Guerra 2013-01-09 16:50:59 +01:00
parent 2fc12781ef
commit 96e372cddc
3 changed files with 47 additions and 12 deletions

View file

@ -98,6 +98,29 @@ exposing clojure functions to rhino::
user=> (js/eval scope "add(1, 2)")
3.0
exposing objects with functions::
user=> (require '[clj-rhino :as js])
nil
user=> (defn add [ctx scope this [a b]] (+ a b))
#'user/add
user=> (defn mul [ctx scope this [a b]] (* a b))
#'user/mul
user=> (def scope (js/new-safe-scope))
#'user/scope
user=> (def api {:add add :multiply mul})
#'user/api
user=> (js/with-context (fn [ctx]
#_=> (js/set! scope "api" (js/to-js api scope ctx))
#_=> (js/eval scope "api.add(1, 2) + api.multiply(2, 3)")))
9.0
license?
--------

View file

@ -39,6 +39,16 @@
(to-js (seq obj) scope ctx)
(throw (Exception. (str "Don't know how to convert to rhino " (class obj))))))
(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))))
(extend nil RhinoConvertible {:-to-rhino return-self})
(extend java.lang.Boolean RhinoConvertible {:-to-rhino return-self})
@ -58,6 +68,10 @@
(extend java.util.Map RhinoConvertible {:-to-rhino to-js-object})
(extend java.util.Collection RhinoConvertible {:-to-rhino to-js-array})
;; Functions
(extend clojure.lang.Fn RhinoConvertible {:-to-rhino (fn [obj scope ctx]
(make-fn obj))})
;; Maybe a Java array, otherwise fail
(extend java.lang.Object RhinoConvertible {:-to-rhino to-js-generic})
@ -200,12 +214,3 @@
(or filename "<eval>")
(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))))

View file

@ -161,9 +161,16 @@
(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))))))
(let [scope (js/new-safe-scope)
add (fn [ctx scope this [a b]] (+ a b))
multiply (fn [ctx scope this [a b]] (* a b))
api {:add add :multiply multiply}]
(js/set! scope "add" (js/make-fn add))
(js/set! scope "api" (js/to-js api scope ctx))
(is (= (js/eval scope "add(1, 2)") 3.0))
(is (= (js/eval scope "api.add(1, 2) + api.multiply(2, 3)") 9.0))
))))
)