diff options
| author | Asko Nõmm <asko@nmm.ee> | 2025-09-24 21:57:57 +0300 |
|---|---|---|
| committer | Asko Nõmm <asko@nmm.ee> | 2025-09-24 21:57:57 +0300 |
| commit | d98e13761fdcaa8cba912d367670855087b29c01 (patch) | |
| tree | 878ae923514b95168b6943be4a8ee7dbee1d81a6 | |
| parent | 13f7093cfc9860dc2a9b2fd94f19d3661f15b3d3 (diff) | |
Improve $ macro clj-kondo hook, impl fragment node (well, not really a node itself, but any node with a name of :<> will replace itself with its children.
| -rw-r--r-- | resources/clj-kondo/hooks/dompa.clj | 19 | ||||
| -rw-r--r-- | src/dompa/nodes.cljc | 30 | ||||
| -rw-r--r-- | src/dompa/utils.cljc | 19 |
3 files changed, 43 insertions, 25 deletions
diff --git a/resources/clj-kondo/hooks/dompa.clj b/resources/clj-kondo/hooks/dompa.clj index 2433051..31ab3d3 100644 --- a/resources/clj-kondo/hooks/dompa.clj +++ b/resources/clj-kondo/hooks/dompa.clj @@ -1,7 +1,7 @@ (ns hooks.dompa (:require [clj-kondo.hooks-api :as api])) -(defn string-like? [x] +(defn str-able? [x] (or (api/string-node? x) (api/token-node? x))) @@ -13,7 +13,7 @@ ; strings, i.e. whatever (str) can do. (or (api/string-node? first-arg) (api/token-node? first-arg)) - (let [invalid-args (filter #(not (string-like? %)) rest-args)] + (let [invalid-args (filter #(not (str-able? %)) rest-args)] (doall (for [invalid-arg invalid-args] (api/reg-finding! @@ -34,7 +34,16 @@ "the second argument must be a sequence or a map. " "In other words, the second argument must be an attribute map " "or sequence of other nodes created with the $ macro.") - :type :dompa.utils/$-arg-validation))))) + :type :dompa.utils/$-arg-validation)) - ; if the first arg is a keyword, the second arg is a map, then the third arg can - ; only be a sequence + ; if the first arg is a keyword, the second arg is a map, then from + ; the second forwards everything has to be a list node + (and (api/keyword-node? first-arg) + (api/map-node? (first rest-args)) + (not (every? #(api/list-node? %) (rest rest-args)))) + (api/reg-finding! + (assoc (meta (second rest-args)) + :message (str "Invalid argument type. When having a attribute map, " + "the rest of the arguments must be a $ macro or a sequence " + "of $ macros") + :type :dompa.utils/$-arg-validation))))) diff --git a/src/dompa/nodes.cljc b/src/dompa/nodes.cljc index 295e755..d72aa75 100644 --- a/src/dompa/nodes.cljc +++ b/src/dompa/nodes.cljc @@ -13,19 +13,27 @@ (defn- node->html-reducer-fn [void-nodes nodes->html-fn] (fn [html node] - (when-not (nil? node) - (let [node-name (-> node :node/name name) - node-attrs (reduce-kv node-attrs-reducer "" (-> node :node/attrs))] - (cond - (= (-> node :node/name) :dompa/text) - (str html (-> node :node/value)) + (cond + ; fragment nodes expand their children to replace themselves + (and (not (nil? node)) + (= (:node/name node) :<>)) + (str html (nodes->html-fn (:node/children node))) - (contains? void-nodes (-> node :node/name)) - (str html "<" node-name node-attrs">") + ; otherwise business as usual + :else + (when-not (nil? node) + (let [node-name (-> node :node/name name) + node-attrs (reduce-kv node-attrs-reducer "" (-> node :node/attrs))] + (cond + (= (-> node :node/name) :dompa/text) + (str html (-> node :node/value)) - :else - (let [value (nodes->html-fn (-> node :node/children))] - (str html "<" node-name node-attrs ">" value "</" node-name ">"))))))) + (contains? void-nodes (-> node :node/name)) + (str html "<" node-name node-attrs">") + + :else + (let [value (nodes->html-fn (-> node :node/children))] + (str html "<" node-name node-attrs ">" value "</" node-name ">")))))))) (defn traverse "Recursively traverses given tree of `nodes` with a `traverser-fn` diff --git a/src/dompa/utils.cljc b/src/dompa/utils.cljc index 9e1cb27..0396e8a 100644 --- a/src/dompa/utils.cljc +++ b/src/dompa/utils.cljc @@ -12,12 +12,12 @@ (fn [rf] (letfn [(step [result input] (if (sequential? input) - (reduce step result input) ;; recursively reduce over nested seq - (rf result input)))] ;; apply rf with accumulator + value + (reduce step result input) + (rf result input)))] (fn - ([] (rf)) ;; init - ([result] (rf result)) ;; completion - ([result input] (step result input)))))) ;; step + ([] (rf)) + ([result] (rf result)) + ([result input] (step result input)))))) (defn ->flat [children] (into [] (->flat-xf) children)) @@ -39,9 +39,10 @@ (defhtml test-page [] (let [n 123] - ($ :div - ($ "hello world" n)) - ($ "hello") - ($ :div (map #(%) []) "test"))) + ($ :<> + ($ :div + ($ "hello world" n)) + ($ "hello") + ($ :div)))) (test-page) |
