From 6c8e76d571a03594b7312f9807a87540c1aeff8b Mon Sep 17 00:00:00 2001 From: Ferdinand Beyer Date: Mon, 16 Sep 2024 12:30:36 +0200 Subject: [PATCH] Evaluate vector and map attributes --- src/hiccup/compiler.clj | 22 +++++++++++----------- test/hiccup2/core_test.clj | 11 ++++++++++- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/hiccup/compiler.clj b/src/hiccup/compiler.clj index e1db82f..4930ea4 100644 --- a/src/hiccup/compiler.clj +++ b/src/hiccup/compiler.clj @@ -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)) @@ -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." @@ -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] diff --git a/test/hiccup2/core_test.clj b/test/hiccup2/core_test.clj index cb20141..6eb45f3 100644 --- a/test/hiccup2/core_test.clj +++ b/test/hiccup2/core_test.clj @@ -7,7 +7,7 @@ (testing "html returns a RawString" (is (util/raw-string? (html [:div])))) (testing "converting to string" - (= (str (html [:div])) "
"))) + (is (= (str (html [:div])) "
")))) (deftest tag-names (testing "basic tags" @@ -115,6 +115,15 @@ "")) (is (= (str (html [:div {:id (str "a" "b")} (str "foo")])) "
foo
"))) + (testing "vector attributes are evaluated" + (let [x "bar"] + (is (= (str (html [:span {:class ["foo" x]}])) + "")))) + (testing "map attributes are evaluated" + (let [color "red" + bg-color :blue] + (is (= (str (html [:span {:style {:background-color bg-color, :color color}} "foo"])) + "foo")))) (testing "type hints" (let [string "x"] (is (= (str (html [:span ^String string])) "x"))))