diff options
| -rw-r--r-- | src/dompa/coordinates.cljc | 45 | ||||
| -rw-r--r-- | src/dompa/nodes.cljc | 27 | ||||
| -rw-r--r-- | test/dompa/nodes_test.cljc | 2 |
3 files changed, 56 insertions, 18 deletions
diff --git a/src/dompa/coordinates.cljc b/src/dompa/coordinates.cljc index 2d7e29d..8cdcd7d 100644 --- a/src/dompa/coordinates.cljc +++ b/src/dompa/coordinates.cljc @@ -2,6 +2,8 @@ (:require [clojure.string :as str])) (defn- compose-reducer-fn + "Returns a reducer function with initial state of + `total-char-count` integer." [total-char-count] (fn [{:keys [char-type start-idx coordinates] :as state} [idx c]] (cond @@ -67,6 +69,14 @@ :coordinates)})) (defn- coordinates->tag-name + "Parses the given `html` string between the indexes of `start` + and `end` for an HTML tag name. + + ```html + <div>hello</div> + ``` + + Would become: `div`." [html [start end]] (let [value (subs html start end)] (if (str/starts-with? value "<") @@ -77,11 +87,16 @@ value))) (defn- name-coordinates-fn + "Returns a function with the initial state of an `html` + string, to be used to construct a sequence of `[index, name]`. " [html] (fn [idx coordinate] [idx (coordinates->tag-name html coordinate)])) (defn- last-by-tag-name-idx + "Gets the last coordinate matching the tag `name` that occurred + before `start`, for finding coordinates that should be merged + together." [html coordinates name start] (let [filter-fn (fn [[_ end]] (< end start)) filtered-coordinates (filter filter-fn coordinates) @@ -102,6 +117,8 @@ coordinates))) (defn- unify-reducer-fn + "Returns a reducer function with the initial state of + a `html` string." [html] (fn [coordinates [start end]] (if (and (= \< (nth html start)) @@ -127,6 +144,8 @@ (reduce [] coordinates))}) (defn- children + "Returns all the coordinates that belong between the given + `from` and `to` indexes." [coordinates [from to]] (->> coordinates (filter (fn [[iter-from iter-to]] @@ -135,6 +154,8 @@ (sort-by first))) (defn- without-children + "Returns all the coordinates that do not belong between + the given `parent-from` and `parent-to` indexes." [coordinates [parent-from parent-to]] (->> coordinates (remove (fn [[from to]] @@ -181,7 +202,8 @@ v (if (nil? v) true (normalize-html-attr-str v))] {k v})) -(defn- html->str->node-attrs-reducer +(defn- html->str->node-attrs-reducer-fn + "Returns a reducer function with initial state of `attrs-html`." [attrs-html] (fn [{:keys [start-idx has-attrs? attrs] :as state} [idx c]] (cond @@ -220,7 +242,20 @@ :else state))) -(defn- html->str->attrs-html-str [html] +(defn- html->attrs-html + "Transforms a given `html` string into a string portion of + just the attributes. + + ```html + <div class=\"test\"></div> + ``` + + would become + + ``` + class=\"test\" + ```" + [html] (->> (subs html 1) (take-while #(not (contains? #{\> \/} %))) (partition-by #(= % \space)) @@ -244,18 +279,20 @@ ```" [html] (when (str/starts-with? html "<") - (let [attrs-html (html->str->attrs-html-str html) + (let [attrs-html (html->attrs-html html) indexed-attrs-html (map-indexed vector attrs-html) default-reducer-state {:start-idx 0 :has-attrs? false :attrs []}] - (as-> (html->str->node-attrs-reducer attrs-html) $ + (as-> (html->str->node-attrs-reducer-fn attrs-html) $ (reduce $ default-reducer-state indexed-attrs-html) (remove str/blank? (:attrs $)) (map parse-html-attr-str $) (into {} $))))) (defn- construct-node + "Constructs a node map from `node-html` string and + its children nodes." [node-html node-children] (let [node-name (html-str->node-name node-html) node-attrs (html-str->node-attrs node-html)] diff --git a/src/dompa/nodes.cljc b/src/dompa/nodes.cljc index 24d446e..a434cf0 100644 --- a/src/dompa/nodes.cljc +++ b/src/dompa/nodes.cljc @@ -11,6 +11,8 @@ (str attrs " " attr-name "=\"" v "\"")))) (defn- node->html-reducer-fn + "Returns a reducer function with the initial state of `void-nodes` + set and `nodes->html-fn` function for recursive HTML creation." [void-nodes nodes->html-fn] (fn [html node] (cond @@ -20,20 +22,19 @@ (str html (nodes->html-fn (:node/children node))) ; 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)) + (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)) - (contains? void-nodes (-> node :node/name)) - (str html "<" node-name node-attrs">") + (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 ">")))))))) + :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` @@ -110,7 +111,7 @@ (defmacro $ "A helper that simplifies node creation. Particularly useful where you need compile-time composition over run-time, like when - combined with the `defhtml` macro." + combined with the `defhtml` macro to create HTML string outputs." [name & opts] `(if (string? ~name) {:node/name :dompa/text diff --git a/test/dompa/nodes_test.cljc b/test/dompa/nodes_test.cljc index 0e2b63f..a95593d 100644 --- a/test/dompa/nodes_test.cljc +++ b/test/dompa/nodes_test.cljc @@ -2,7 +2,7 @@ (:require [clojure.test :refer [deftest is testing]] [dompa.nodes :refer [$]])) -(deftest node-composition-test +(deftest node-composition-macro-test (testing "a simple node" (is (= {:node/name :div :node/children [{:node/name :dompa/text |
