summaryrefslogtreecommitdiff
path: root/src/dompa/utils.cljc
blob: 0e178752c42839cffd6a52619aaf487f6955a2cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
(ns dompa.utils
  (:require [dompa.nodes :as nodes]
            [criterium.core :as c]))

(defmacro defhtml
  {:clj-kondo/lint-as 'clojure.core/defn}
  [name & args-and-elements]
  (let [[args & elements] args-and-elements]
    `(defn ~name ~args
       (nodes/->html (vector ~@elements)))))

(defn flattench-xf []
  (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
      (fn
        ([] (rf))                                           ;; init
        ([result] (rf result))                              ;; completion
        ([result input] (step result input))))))            ;; step

(defn flattench [children]
  (into [] (flattench-xf) children))

(defmacro $
  {:clj-kondo/lint-as 'clojure.core/list}
  [name & opts]
  `(if (string? ~name)
     {:node/name  :dompa/text
      :node/value (apply str ~name ~@opts)}
     (let [opts# (list ~@opts)
           first-opt# (first opts#)
           attrs?# (and (map? first-opt#)
                        (not (contains? first-opt# :node/name)))
           attrs# (if attrs?# first-opt# {})
           children# (if attrs?# (rest opts#) opts#)]
       (cond-> {:node/name ~name}
               attrs?# (assoc :node/attrs attrs#)
               (seq children#) (assoc :node/children (flattench children#))))))

(defn bench-n []
  (c/quick-bench
    (dotimes [_ 1500]
      ($ :div {:class "container"}
          (map #($ %) ["a" "b" "c"])
          ($ "hello world")))))

(defhtml test-page []
  ($ :div
      (map #($ %) ["a" "b" "c"])
      ($ "hello world")))

(test-page)