Skip to content

Commit 92f18b7

Browse files
authored
Merge pull request #208 from luontola/detect-runtime-attrs-vs-content
Fix formatting of nil attributes at runtime
2 parents 4d7303c + 7196a47 commit 92f18b7

File tree

3 files changed

+31
-24
lines changed

3 files changed

+31
-24
lines changed

src/hiccup/compiler.clj

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -331,26 +331,34 @@
331331
(compile-element (apply vector tag {} content)))
332332

333333
(defmethod compile-element ::literal-tag
334-
[[tag attrs & content]]
334+
[[tag attrs-or-content & content]]
335335
(let [[tag tag-attrs _] (normalize-element-form [tag])
336-
attrs-sym (gensym "attrs")]
337-
`(let [~attrs-sym ~attrs]
336+
attrs-or-content-sym (gensym "attrs_or_content__")
337+
attrs?-sym (gensym "attrs?__")
338+
content?-sym (gensym "content?__")]
339+
`(let [~attrs-or-content-sym ~attrs-or-content
340+
~attrs?-sym (map? ~attrs-or-content-sym)
341+
~content?-sym (and (not ~attrs?-sym)
342+
(some? ~attrs-or-content-sym))]
338343
(build-string
339-
(if (map? ~attrs-sym)
340-
~(if (container-tag? tag content)
341-
`(build-string ~(str "<" tag)
342-
(render-attr-map (merge ~tag-attrs ~attrs-sym))
343-
">")
344-
`(build-string ~(str "<" tag)
345-
(render-attr-map (merge ~tag-attrs ~attrs-sym))
346-
~(end-tag)))
347-
(build-string ~(str "<" tag (render-attr-map tag-attrs) ">")
348-
~@(compile-seq [attrs-sym])))
344+
;; start tag
345+
"<" ~tag
346+
(if ~attrs?-sym
347+
(render-attr-map (merge ~tag-attrs ~attrs-or-content-sym))
348+
~(render-attr-map tag-attrs))
349+
~(if (container-tag? tag content)
350+
">"
351+
`(if ~content?-sym ">" ~(end-tag)))
352+
353+
;; contents
354+
(when ~content?-sym
355+
(render-html ~attrs-or-content-sym))
349356
~@(compile-seq content)
350-
;; ending tag, when the above code did not emit an ending tag
357+
358+
;; end tag
351359
~(if (container-tag? tag content)
352360
(str "</" tag ">")
353-
`(when-not (map? ~attrs-sym)
361+
`(when ~content?-sym
354362
~(str "</" tag ">")))))))
355363

356364
(defmethod compile-element ::default

test/hiccup/compiler_test.clj

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,17 @@
5353
(is (= (str (html {:mode :sgml} [:br (identity "x")])) "<br>x</br>"))))
5454

5555
(testing "runtime nil,"
56+
;; use case: a function which returns a map of attributes or nil
5657
(testing "normal tag"
5758
(is (= (str (html {:mode :xhtml} [:p (identity nil)])) "<p></p>"))
5859
(is (= (str (html {:mode :html} [:p (identity nil)])) "<p></p>"))
59-
(is (= (str (html {:mode :xml} [:p (identity nil)])) "<p></p>"))
60-
(is (= (str (html {:mode :sgml} [:p (identity nil)])) "<p></p>")))
60+
(is (= (str (html {:mode :xml} [:p (identity nil)])) "<p />"))
61+
(is (= (str (html {:mode :sgml} [:p (identity nil)])) "<p>")))
6162
(testing "void tag"
62-
;; TODO: this might not be desired behavior (use case: the user has
63-
;; a function which returns a map of attributes or nil)
64-
(is (= (str (html {:mode :xhtml} [:br (identity nil)])) "<br></br>"))
65-
(is (= (str (html {:mode :html} [:br (identity nil)])) "<br></br>"))
66-
(is (= (str (html {:mode :xml} [:br (identity nil)])) "<br></br>"))
67-
(is (= (str (html {:mode :sgml} [:br (identity nil)])) "<br></br>")))))
63+
(is (= (str (html {:mode :xhtml} [:br (identity nil)])) "<br />"))
64+
(is (= (str (html {:mode :html} [:br (identity nil)])) "<br>"))
65+
(is (= (str (html {:mode :xml} [:br (identity nil)])) "<br />"))
66+
(is (= (str (html {:mode :sgml} [:br (identity nil)])) "<br>")))))
6867

6968
(deftest test-compile-element-default
7069
(testing "runtime tag"

test/hiccup2/optimizations_test.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,4 @@
7575
(partition 2 1)
7676
(map (fn [[a b]] (- b a))))]
7777
(is (< (apply max diffs)
78-
(* 1.1 (apply min diffs)))))))
78+
(* 1.2 (apply min diffs)))))))

0 commit comments

Comments
 (0)