Skip to content

Commit

Permalink
Merge pull request #214 from ferdinand-beyer/eval-attrs
Browse files Browse the repository at this point in the history
Evaluate vector and map attributes

Fixes a bug where the compiler emits unevaluated forms within vector or
map attributes.
  • Loading branch information
weavejester authored Oct 31, 2024
2 parents 5a6d45c + 6c8e76d commit 9fd4053
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 12 deletions.
22 changes: 11 additions & 11 deletions src/hiccup/compiler.clj
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
content])))

(defn normalize-element
"Ensure an element vector is of the form [tag-name attrs content]."
"Ensure an element vector is of the form [tag-name attrs content]."
[tag-content]
(normalize-element* tag-content merge-attributes))

Expand Down Expand Up @@ -217,13 +217,20 @@
(and (seq? expr)
(not= (first expr) `quote))))

(defn- literal?
"True if x is a literal value that can be rendered as-is."
[x]
(and (not (unevaluated? x))
(or (not (or (vector? x) (map? x)))
(every? literal? x))))

(defn compile-attr-map
"Returns an unevaluated form that will render the supplied map as HTML
attributes."
[attrs]
(if (some unevaluated? (mapcat identity attrs))
`(render-attr-map ~attrs)
(render-attr-map attrs)))
(if (every? literal? (mapcat identity attrs))
(render-attr-map attrs)
`(render-attr-map ~attrs)))

(defn- form-name
"Get the name of the supplied form."
Expand Down Expand Up @@ -276,13 +283,6 @@
(if-let [hint (-> x meta :tag)]
(isa? (eval hint) type)))

(defn- literal?
"True if x is a literal value that can be rendered as-is."
[x]
(and (not (unevaluated? x))
(or (not (or (vector? x) (map? x)))
(every? literal? x))))

(defn- not-implicit-map?
"True if we can infer that x is not a map."
[x]
Expand Down
11 changes: 10 additions & 1 deletion test/hiccup2/core_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
(testing "html returns a RawString"
(is (util/raw-string? (html [:div]))))
(testing "converting to string"
(= (str (html [:div])) "<div></div>")))
(is (= (str (html [:div])) "<div></div>"))))

(deftest tag-names
(testing "basic tags"
Expand Down Expand Up @@ -115,6 +115,15 @@
"<img src=\"/foo/bar\" />"))
(is (= (str (html [:div {:id (str "a" "b")} (str "foo")]))
"<div id=\"ab\">foo</div>")))
(testing "vector attributes are evaluated"
(let [x "bar"]
(is (= (str (html [:span {:class ["foo" x]}]))
"<span class=\"foo bar\"></span>"))))
(testing "map attributes are evaluated"
(let [color "red"
bg-color :blue]
(is (= (str (html [:span {:style {:background-color bg-color, :color color}} "foo"]))
"<span style=\"background-color:blue;color:red;\">foo</span>"))))
(testing "type hints"
(let [string "x"]
(is (= (str (html [:span ^String string])) "<span>x</span>"))))
Expand Down

0 comments on commit 9fd4053

Please sign in to comment.