From 2239b96f4a8dc5c61ff228d1fd2504bf66ae3903 Mon Sep 17 00:00:00 2001 From: Esko Luontola Date: Sun, 3 Dec 2023 15:19:39 +0200 Subject: [PATCH] Fix literal child elements being escaped Fix a form like: (html [(identity :p) [:span "x"]]) Evaluating to: "

<span>x</span>

" Instead of: "

x

" --- src/hiccup/compiler.clj | 10 +++++----- test/hiccup/compiler_test.clj | 35 +++++++++++++++++++++-------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/hiccup/compiler.clj b/src/hiccup/compiler.clj index 4b57b25..0533f74 100644 --- a/src/hiccup/compiler.clj +++ b/src/hiccup/compiler.clj @@ -356,11 +356,11 @@ (defmethod compile-element ::default [element] `(render-element - [~(first element) - ~@(for [x (rest element)] - (if (vector? x) - (compile-element x) - x))])) + [~(first element) + ~@(for [x (rest element)] + (if (vector? x) + (util/raw-string (compile-element x)) + x))])) (defn- compile-seq "Compile a sequence of data-structures into HTML." diff --git a/test/hiccup/compiler_test.clj b/test/hiccup/compiler_test.clj index 552e219..91b3830 100644 --- a/test/hiccup/compiler_test.clj +++ b/test/hiccup/compiler_test.clj @@ -1,6 +1,15 @@ (ns hiccup.compiler-test (:require [clojure.test :refer :all] - [hiccup2.core :refer [html]])) + [clojure.walk :as walk] + [hiccup2.core :refer [html]]) + (:import (hiccup.util RawString))) + +(defn- extract-strings [code] + (->> (tree-seq coll? seq code) + (filter #(or (string? %) + (instance? RawString %))) + (map str) + (set))) (deftest test-compile-element-literal-tag ;; `compile-element ::literal-tag` behavior varies based on the following @@ -93,21 +102,19 @@ "

x

"))) (testing "runtime tag with child elements" - ;; FIXME: this should return "

x

" (is (= (str (html {:mode :xhtml} [(identity :p) [:span "x"]])) - "

<span>x</span>

")) + (str (html {:mode :xhtml} [(identity :p) (identity [:span "x"])])) + "

x

")) (is (= (str (html {:mode :html} [(identity :p) [:span "x"]])) - "

<span>x</span>

")) + (str (html {:mode :html} [(identity :p) (identity [:span "x"])])) + "

x

")) (is (= (str (html {:mode :xml} [(identity :p) [:span "x"]])) - "

<span>x</span>

")) + (str (html {:mode :xml} [(identity :p) (identity [:span "x"])])) + "

x

")) (is (= (str (html {:mode :sgml} [(identity :p) [:span "x"]])) - "

<span>x</span>

")) + (str (html {:mode :sgml} [(identity :p) (identity [:span "x"])])) + "

x

"))) - (is (= (str (html {:mode :xhtml} [(identity :p) (identity [:span "x"])])) - "

x

")) - (is (= (str (html {:mode :html} [(identity :p) (identity [:span "x"])])) - "

x

")) - (is (= (str (html {:mode :xml} [(identity :p) (identity [:span "x"])])) - "

x

")) - (is (= (str (html {:mode :sgml} [(identity :p) (identity [:span "x"])])) - "

x

")))) + (testing "compiles literal child elements" + (let [code (walk/macroexpand-all `(html [(identity :p) [:span "x"]]))] + (is (= (extract-strings code) #{"" "x"})))))