mirror of
https://github.com/status-im/reagent.git
synced 2025-01-12 04:44:27 +00:00
Refactor template a bit
This commit is contained in:
parent
11a1c62024
commit
4099c00838
@ -2,26 +2,26 @@
|
||||
(ns cloact.impl.template
|
||||
(:require-macros [cloact.debug :refer [dbg prn println]])
|
||||
(:require [clojure.string :as string]
|
||||
[cloact.impl.reactimport :as reacts]
|
||||
[cloact.impl.reactimport :as reactimport]
|
||||
[cloact.impl.util :as util]))
|
||||
|
||||
(def React reacts/React)
|
||||
(def React reactimport/React)
|
||||
|
||||
(def isClient (not (nil? (try (.-document js/window)
|
||||
(catch js/Object e nil)))))
|
||||
|
||||
(defn dash-to-camel [dashed]
|
||||
(let [words (string/split (name dashed) #"-")
|
||||
camels (map string/capitalize (rest words))]
|
||||
(apply str (first words) camels)))
|
||||
(let [words (-> dashed name (string/split #"-"))]
|
||||
(apply str (first words)
|
||||
(->> words rest (map string/capitalize)))))
|
||||
|
||||
(def attr-aliases {"class" "className"
|
||||
"for" "htmlFor"
|
||||
"charset" "charSet"})
|
||||
(def attr-aliases {:class "className"
|
||||
:for "htmlFor"
|
||||
:charset "charSet"})
|
||||
|
||||
(defn undash-prop-name [n]
|
||||
(let [undashed (dash-to-camel n)]
|
||||
(get attr-aliases undashed undashed)))
|
||||
(or (attr-aliases n)
|
||||
(dash-to-camel n)))
|
||||
|
||||
(def cached-prop-name (memoize undash-prop-name))
|
||||
(def cached-style-name (memoize dash-to-camel))
|
||||
@ -34,47 +34,44 @@
|
||||
(ifn? val) (fn [& args] (apply val args))
|
||||
:else (clj->js val)))
|
||||
|
||||
(defn set-tag-extra [props [id class]]
|
||||
(set! (.-id props) id)
|
||||
(defn set-id-class [props [id class]]
|
||||
(aset props "id" id)
|
||||
(when class
|
||||
(set! (.-className props)
|
||||
(if-let [old (.-className props)]
|
||||
(str class " " old)
|
||||
class))))
|
||||
(aset props "className" (if-let [old (aget props "className")]
|
||||
(str class " " old)
|
||||
class))))
|
||||
|
||||
(defn convert-props [props extra]
|
||||
(defn convert-props [props id-class]
|
||||
(let [is-empty (empty? props)]
|
||||
(cond
|
||||
(and is-empty (nil? extra)) nil
|
||||
(and is-empty (nil? id-class)) nil
|
||||
(identical? (type props) js/Object) props
|
||||
:else (let [objprops (js-obj)]
|
||||
(when-not is-empty
|
||||
(doseq [[k v] props]
|
||||
(aset objprops (cached-prop-name k)
|
||||
(convert-prop-value v))))
|
||||
(when-not (nil? extra)
|
||||
(set-tag-extra objprops extra))
|
||||
(when-not (nil? id-class)
|
||||
(set-id-class objprops id-class))
|
||||
objprops))))
|
||||
|
||||
(defn map-into-array [f coll]
|
||||
(let [a (into-array coll)
|
||||
len (alength a)]
|
||||
(dotimes [i len]
|
||||
(let [a (into-array coll)]
|
||||
(dotimes [i (alength a)]
|
||||
(aset a i (f (aget a i))))
|
||||
a))
|
||||
|
||||
(declare as-component)
|
||||
|
||||
(defn wrapped-render [this comp extra]
|
||||
(defn wrapped-render [this comp id-class]
|
||||
(let [inprops (aget this "props")
|
||||
args (.-cljsArgs inprops)
|
||||
[_ scnd] args
|
||||
hasprops (or (nil? scnd) (map? scnd))
|
||||
jsprops (convert-props (if hasprops scnd) extra)
|
||||
jsargs (->> args
|
||||
(drop (if hasprops 2 1))
|
||||
props (nth args 1 nil)
|
||||
hasprops (or (nil? props) (map? props))
|
||||
jsargs (->> (if hasprops (drop 1 args) args)
|
||||
(map-into-array as-component))]
|
||||
(.apply comp nil (.concat (array jsprops) jsargs))))
|
||||
(aset jsargs 0 (convert-props (if hasprops props) id-class))
|
||||
(.apply comp nil jsargs)))
|
||||
|
||||
(defn wrapped-should-update [C nextprops nextstate]
|
||||
(let [a1 (-> C (aget "props") .-cljsArgs)
|
||||
@ -82,16 +79,14 @@
|
||||
(not (util/equal-args a1 a2))))
|
||||
|
||||
(defn wrap-component [comp extras]
|
||||
(let [spec #js {:render #(this-as C (wrapped-render C comp extras))
|
||||
:shouldComponentUpdate
|
||||
#(this-as C (wrapped-should-update C %1 %2))}]
|
||||
(.createClass React spec)))
|
||||
(.createClass React (js-obj "render"
|
||||
#(this-as C (wrapped-render C comp extras))
|
||||
"shouldComponentUpdate"
|
||||
#(this-as C (wrapped-should-update C %1 %2)))))
|
||||
|
||||
;; From Weavejester's Hiccup, via pump:
|
||||
;; https://github.com/weavejester/hiccup/blob/master/src/hiccup/compiler.clj#L32
|
||||
(def ^{:doc "Regular expression that parses a CSS-style id and class
|
||||
from a tag name."
|
||||
:private true}
|
||||
from a tag name."}
|
||||
re-tag #"([^\s\.#]+)(?:#([^\s\.#]+))?(?:\.([^\s#]+))?")
|
||||
|
||||
(def DOM (aget React "DOM"))
|
||||
@ -101,17 +96,17 @@
|
||||
comp (aget DOM tag)
|
||||
class' (when class
|
||||
(string/replace class #"\." " "))]
|
||||
(assert comp (str "Unknown tag: " tag))
|
||||
[comp (when (or id class')
|
||||
[id class'])]))
|
||||
|
||||
(defn get-wrapper [tag]
|
||||
(let [[comp extra] (parse-tag tag)]
|
||||
(wrap-component comp extra)))
|
||||
(let [[comp id-class] (parse-tag tag)]
|
||||
(wrap-component comp id-class)))
|
||||
|
||||
(def cached-wrapper (memoize get-wrapper))
|
||||
|
||||
(defn fn-to-class [f]
|
||||
(assert (fn? f))
|
||||
(let [spec (meta f)
|
||||
withrender (merge spec {:render f})
|
||||
res (cloact.core/create-class withrender)
|
||||
@ -119,26 +114,29 @@
|
||||
(set! (.-cljsReactClass f) wrapf)
|
||||
wrapf))
|
||||
|
||||
(defn as-class [x]
|
||||
(cond
|
||||
(keyword? x) (cached-wrapper x)
|
||||
(not (nil? (.-cljsReactClass x))) (.-cljsReactClass x)
|
||||
:else (do (assert (fn? x))
|
||||
(if (.isValidClass React x)
|
||||
(set! (.-cljsReactClass x) (wrap-component x nil))
|
||||
(fn-to-class x)))))
|
||||
(defn as-class [tag]
|
||||
(if (keyword? tag)
|
||||
(cached-wrapper tag)
|
||||
(do
|
||||
(assert (fn? tag))
|
||||
(let [cached-class (.-cljsReactClass tag)]
|
||||
(if-not (nil? cached-class)
|
||||
cached-class
|
||||
(if (.isValidClass React tag)
|
||||
(set! (.-cljsReactClass tag) (wrap-component tag nil))
|
||||
(fn-to-class tag)))))))
|
||||
|
||||
(defn vec-to-comp [v]
|
||||
(assert (pos? (count v)))
|
||||
(let [[tag props] v
|
||||
c (as-class tag)
|
||||
obj (js-obj)]
|
||||
(set! (.-cljsArgs obj) v)
|
||||
jsprops (js-obj)]
|
||||
(set! (.-cljsArgs jsprops) v)
|
||||
(when (map? props)
|
||||
(let [key (:key props)]
|
||||
(when-not (nil? key)
|
||||
(set! (.-key obj) key))))
|
||||
(c obj)))
|
||||
(aset jsprops "key" key))))
|
||||
(c jsprops)))
|
||||
|
||||
(defn as-component [x]
|
||||
(cond (vector? x) (vec-to-comp x)
|
||||
|
Loading…
x
Reference in New Issue
Block a user