mirror of
https://github.com/status-im/reagent.git
synced 2025-01-13 13:24:47 +00:00
Deprecate reagent.interop ns, fixes #419
This commit is contained in:
parent
1678887627
commit
d4038cb911
@ -13,10 +13,8 @@ to normalize and combine `:class` values (similar to `classnames` JS library)
|
||||
- Fix comparing Reagent `PartialFn` to `nil` ([#385](https://github.com/reagent-project/reagent/issues/385))
|
||||
- Reagent no longer abuses `aget` or `aset` for accessing objects, and instead
|
||||
uses correct Object interop forms, allowing use of ClojureScript `:checked-arrays :warn` option. ([#325](https://github.com/reagent-project/reagent/issues/325))
|
||||
- **Removed `reagent.interop` namespace**
|
||||
- These macros where bad practice and don't work properly if
|
||||
React code is optimized by Closure. Proper object interop forms or `goog.object` functions
|
||||
should be used instead.
|
||||
- Deprecated `reagent.interop` namespace
|
||||
- It is better to use proper object interop forms or `goog.object` functions instead.
|
||||
|
||||
## 0.8.1 (2018-05-15)
|
||||
|
||||
|
91
src/reagent/interop.clj
Normal file
91
src/reagent/interop.clj
Normal file
@ -0,0 +1,91 @@
|
||||
(ns reagent.interop
|
||||
(:require [clojure.string :as string :refer [join]]))
|
||||
|
||||
; taken from cljs.core
|
||||
; https://github.com/binaryage/cljs-oops/issues/14
|
||||
(defmacro unchecked-aget
|
||||
([array idx]
|
||||
(list 'js* "(~{}[~{}])" array idx))
|
||||
([array idx & idxs]
|
||||
(let [astr (apply str (repeat (count idxs) "[~{}]"))]
|
||||
`(~'js* ~(str "(~{}[~{}]" astr ")") ~array ~idx ~@idxs))))
|
||||
|
||||
; taken from cljs.core
|
||||
; https://github.com/binaryage/cljs-oops/issues/14
|
||||
(defmacro unchecked-aset
|
||||
([array idx val]
|
||||
(list 'js* "(~{}[~{}] = ~{})" array idx val))
|
||||
([array idx idx2 & idxv]
|
||||
(let [n (dec (count idxv))
|
||||
astr (apply str (repeat n "[~{}]"))]
|
||||
`(~'js* ~(str "(~{}[~{}][~{}]" astr " = ~{})") ~array ~idx ~idx2 ~@idxv))))
|
||||
|
||||
(defn- js-call [f args]
|
||||
(let [argstr (->> (repeat (count args) "~{}")
|
||||
(join ","))]
|
||||
(list* 'js* (str "~{}(" argstr ")") f args)))
|
||||
|
||||
(defn- dot-args [object member]
|
||||
(assert (or (symbol? member)
|
||||
(keyword? member))
|
||||
(str "Symbol or keyword expected, not " (pr-str member)))
|
||||
(assert (or (not (symbol? object))
|
||||
(not (re-find #"\." (name object))))
|
||||
(str "Dot not allowed in " object))
|
||||
(let [n (name member)
|
||||
field? (or (keyword? member)
|
||||
(= (subs n 0 1) "-"))
|
||||
names (-> (if (symbol? member)
|
||||
(string/replace n #"^-" "")
|
||||
n)
|
||||
(string/split #"\."))]
|
||||
[field? names]))
|
||||
|
||||
(defonce $-warning
|
||||
(delay
|
||||
(try
|
||||
(cljs.util/debug-prn "WARNING: reagent.interop/$ has been deprecated. Consider using ClojureScript JS-interop forms or goog.object namespace instead.")
|
||||
(catch Exception _ nil))))
|
||||
|
||||
(defmacro $
|
||||
"Access member in a javascript object, in a Closure-safe way.
|
||||
'member' is assumed to be a field if it is a keyword or if
|
||||
the name starts with '-', otherwise the named function is
|
||||
called with the optional args.
|
||||
'member' may contain '.', to allow access in nested objects.
|
||||
If 'object' is a symbol it is not allowed contain '.'.
|
||||
|
||||
($ o :foo) is equivalent to (.-foo o), except that it gives
|
||||
the same result under advanced compilation.
|
||||
($ o foo arg1 arg2) is the same as (.foo o arg1 arg2)."
|
||||
{:deprecated true}
|
||||
[object member & args]
|
||||
@$-warning
|
||||
(let [[field names] (dot-args object member)]
|
||||
(if field
|
||||
(do
|
||||
(assert (empty? args)
|
||||
(str "Passing args to field doesn't make sense: " member))
|
||||
`(unchecked-aget ~object ~@names))
|
||||
(js-call (list* 'reagent.interop/unchecked-aget object names) args))))
|
||||
|
||||
(defonce $!-warning
|
||||
(delay
|
||||
(try
|
||||
(cljs.util/debug-prn "WARNING: reagent.interop/$! has been deprecated. Consider using ClojureScript JS-interop forms or goog.object namespace instead.")
|
||||
(catch Exception _ nil))))
|
||||
|
||||
(defmacro $!
|
||||
"Set field in a javascript object, in a Closure-safe way.
|
||||
'field' should be a keyword or a symbol starting with '-'.
|
||||
'field' may contain '.', to allow access in nested objects.
|
||||
If 'object' is a symbol it is not allowed contain '.'.
|
||||
|
||||
($! o :foo 1) is equivalent to (set! (.-foo o) 1), except that it
|
||||
gives the same result under advanced compilation."
|
||||
{:deprecated true}
|
||||
[object field value]
|
||||
@$!-warning
|
||||
(let [[field names] (dot-args object field)]
|
||||
(assert field (str "Field name must start with - in " field))
|
||||
`(unchecked-aset ~object ~@names ~value)))
|
2
src/reagent/interop.cljs
Normal file
2
src/reagent/interop.cljs
Normal file
@ -0,0 +1,2 @@
|
||||
(ns reagent.interop
|
||||
(:require-macros [reagent.interop]))
|
@ -6,6 +6,7 @@
|
||||
[reagenttest.testtrack]
|
||||
[reagenttest.testwithlet]
|
||||
[reagenttest.testwrap]
|
||||
[reagenttest.testinterop]
|
||||
[reagent.impl.template-test]
|
||||
[reagent.impl.util-test]
|
||||
[cljs.test :as test]
|
||||
|
56
test/reagenttest/testinterop.cljs
Normal file
56
test/reagenttest/testinterop.cljs
Normal file
@ -0,0 +1,56 @@
|
||||
(ns reagenttest.testinterop
|
||||
(:require [cljs.test :as t :refer-macros [is deftest]]
|
||||
[reagent.debug :refer-macros [dbg]]
|
||||
[reagent.interop :refer-macros [$ $!]]))
|
||||
|
||||
;; (def is-adv (let [o #js{}]
|
||||
;; (set! (.-somethinglong o) true)
|
||||
;; (not= (aget (.keys js/Object o) 0) "somethinglong")))
|
||||
|
||||
(deftest iterop-quote
|
||||
(let [o #js{:foo "foo"
|
||||
:foobar #js{:bar "bar"
|
||||
:bar-foo "bar-foo"}
|
||||
:bar-foo "barfoo"}]
|
||||
|
||||
(is (= "foo" ($ o :foo)))
|
||||
(is (= "bar" ($ o :foobar.bar)))
|
||||
(is (= "barfoo" ($ o :bar-foo)))
|
||||
|
||||
(is (= "foo" ($ o -foo)))
|
||||
(is (= "bar" ($ o -foobar.bar)))
|
||||
(is (= "bar-foo" ($ o -foobar.bar-foo)))
|
||||
(is (= "bar-foo" ($ o :foobar.bar-foo)))
|
||||
|
||||
($! o :foo "foo1")
|
||||
(is (= "foo1" ($ o :foo)))
|
||||
|
||||
($! o -foo "foo2")
|
||||
(is (= "foo2" ($ o -foo)))
|
||||
|
||||
($! o :foobar.bar "bar1")
|
||||
(is (= "bar1" ($ o :foobar.bar)))
|
||||
|
||||
($! o -foobar.bar "bar1")
|
||||
(is (= "bar1" ($ o -foobar.bar)))))
|
||||
|
||||
(deftest interop-quote-call
|
||||
(let [o #js{:bar "bar1"
|
||||
:foo (fn [x]
|
||||
(this-as this
|
||||
(str x ($ this :bar))))}
|
||||
o2 #js{:o o}]
|
||||
(is (= "ybar1" ($ o foo "y")))
|
||||
(is (= "xxbar1" ($ o2 o.foo "xx")))
|
||||
(is (= "abar1" (-> o2
|
||||
($ :o)
|
||||
($ foo "a"))))
|
||||
|
||||
(is (= "bar1" ($ o foo)))
|
||||
(is (= "bar1" ($ o2 o.foo)))
|
||||
|
||||
($! o :bar "bar2")
|
||||
(is (= "bar2" ($ o foo)))
|
||||
|
||||
(is (= "1bar2" ($ ($ o :foo)
|
||||
call o 1)))))
|
Loading…
x
Reference in New Issue
Block a user