Merge pull request #323 from reagent-project/custom-element-props-names

Don't rename props for custom elements
This commit is contained in:
Juho Teperi 2017-11-18 20:39:41 +02:00 committed by GitHub
commit abe799e20f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 19 deletions

View File

@ -71,6 +71,33 @@
(apply x args)) (apply x args))
:else (clj->js x))) :else (clj->js x)))
;; Previous few functions copied for custom elements,
;; without mapping from class to className etc.
(def custom-prop-name-cache #js{})
(defn cached-custom-prop-name [k]
(if (named? k)
(if-some [k' (cache-get custom-prop-name-cache (name k))]
k'
(aset prop-name-cache (name k)
(util/dash-to-camel k)))
k))
(defn custom-kv-conv [o k v]
(doto o
(aset (cached-custom-prop-name k)
(convert-prop-value v))))
(defn convert-custom-prop-value [x]
(cond (js-val? x) x
(named? x) (name x)
(map? x) (reduce-kv custom-kv-conv #js{} x)
(coll? x) (clj->js x)
(ifn? x) (fn [& args]
(apply x args))
:else (clj->js x)))
(defn oset [o k v] (defn oset [o k v]
(doto (if (nil? o) #js{} o) (doto (if (nil? o) #js{} o)
(aset k v))) (aset k v)))
@ -78,18 +105,22 @@
(defn oget [o k] (defn oget [o k]
(if (nil? o) nil (aget o k))) (if (nil? o) nil (aget o k)))
(defn set-id-class [p id-class] (defn set-id-class
"Takes the id and class from tag keyword, and adds them to the
other props. Parsed tag is JS object with :id and :class properties."
[props id-class]
(let [id ($ id-class :id) (let [id ($ id-class :id)
p (if (and (some? id) class ($ id-class :class)]
(nil? (oget p "id"))) (cond-> props
(oset p "id" id) ;; Only use ID from tag keyword if no :id in props already
p)] (and (some? id)
(if-some [class ($ id-class :className)] (nil? (:id props)))
(let [old (oget p "className")] (assoc :id id)
(oset p "className" (if (nil? old)
class ;; Merge classes
(str class " " old)))) class
p))) (assoc :class (let [old-class (:class props)]
(if (nil? old-class) class (str class " " old-class)))))))
(defn stringify-class [{:keys [class] :as props}] (defn stringify-class [{:keys [class] :as props}]
(if (coll? class) (if (coll? class)
@ -100,10 +131,12 @@
props)) props))
(defn convert-props [props id-class] (defn convert-props [props id-class]
(-> props (let [props (-> props
stringify-class stringify-class
convert-prop-value (set-id-class id-class))]
(set-id-class id-class))) (if ($ id-class :custom)
(convert-custom-prop-value props)
(convert-prop-value props))))
;;; Specialization for input components ;;; Specialization for input components
@ -134,7 +167,7 @@
($! node :value rendered-value) ($! node :value rendered-value)
(when (fn? on-write) (when (fn? on-write)
(on-write rendered-value))) (on-write rendered-value)))
;; Setting "value" (below) moves the cursor position to the ;; Setting "value" (below) moves the cursor position to the
;; end which gives the user a jarring experience. ;; end which gives the user a jarring experience.
;; ;;
@ -280,9 +313,12 @@
(string/replace class #"\." " "))] (string/replace class #"\." " "))]
(assert tag (str "Invalid tag: '" hiccup-tag "'" (assert tag (str "Invalid tag: '" hiccup-tag "'"
(comp/comp-name))) (comp/comp-name)))
#js{:name tag #js {:name tag
:id id :id id
:className class})) :class class
;; Custom element names must contain hyphen
;; https://www.w3.org/TR/custom-elements/#custom-elements-core-concepts
:custom (not= -1 (.indexOf tag "-"))}))
(defn try-get-key [x] (defn try-get-key [x]
;; try catch to avoid clojurescript peculiarity with ;; try catch to avoid clojurescript peculiarity with

View File

@ -1064,3 +1064,12 @@
(is (re-find #"<div style=\"text-align:center(;?)\">foo</div>" (is (re-find #"<div style=\"text-align:center(;?)\">foo</div>"
(server/render-to-static-markup (server/render-to-static-markup
[:div {:style {:text-align "center"}} "foo"])))) [:div {:style {:text-align "center"}} "foo"]))))
(deftest custom-element-class-prop
(is (re-find #"<custom-element class=\"foobar\">foo</custom-element>"
(server/render-to-static-markup
[:custom-element {:class "foobar"} "foo"])))
(is (re-find #"<custom-element class=\"foobar\">foo</custom-element>"
(server/render-to-static-markup
[:custom-element.foobar "foo"]))) )