diff --git a/README.md b/README.md index 7b070ad..2b4f388 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,21 @@ or add the following to your `project.clj` ([Leiningen](https://leiningen.org/)) (h/render [:html [:body ...]]) ``` +## Differences between Lambda Island Hiccup and other implementation. + +We try to minimize differences between Lambda Island Hiccup and Reagent, first +and foremost. Whenver possible, we try to minimize differences between between Lambda Island Hiccup and the original Hiccup as well. + +There are no known semantic differences in the resulting HTML, but there are some minor differences if +you are comparing the output character-for-character and one runtime +difference: + +* When attributes are specified in both the tag name and a map, attributes may appear in a different order. +* The CSS in `style` attributes has different whitespace. +* Illegal tags throw `clojure.lang.ExceptionInfo`, instead of + `IllegalArgumentException`, as in Hiccup, or `AssertionError`, as in Reagent. + + ## Lambda Island Open Source diff --git a/src/lambdaisland/hiccup.clj b/src/lambdaisland/hiccup.clj index 007df5e..eda0bd5 100644 --- a/src/lambdaisland/hiccup.clj +++ b/src/lambdaisland/hiccup.clj @@ -89,7 +89,7 @@ (= :<> tag) (enlive/flatmap #(nodify % opts) more) - (keyword? tag) + (or (keyword? tag) (symbol? tag) (string? tag)) (let [[tag-name & segments] (.split (name tag) "(?=[#.])") id (some (fn [^String seg] (when (= \# (.charAt seg 0)) (subs seg 1))) segments) @@ -107,7 +107,8 @@ (map (fn [[k v]] [(convert-attribute k) v])) (into {})))) - node (if id (assoc-in node [:attrs :id] id) node) + node (if (and id (not (contains? (:attrs node) :id))) + (assoc-in node [:attrs :id] id) node) node (if (seq classes) (update-in node [:attrs "class"] diff --git a/test/lambdaisland/hiccup_test.clj b/test/lambdaisland/hiccup_test.clj index 2abbaf1..3e93b61 100644 --- a/test/lambdaisland/hiccup_test.clj +++ b/test/lambdaisland/hiccup_test.clj @@ -76,3 +76,95 @@ (is (= (str "
") (hiccup/render [:div {input "baz"}] {:doctype? false}))))))) +;borrowed from Hiccup: + +(defmacro html [& body] + `(hiccup/render ~@body {:doctype? false})) + +(deftest tag-names + (testing "basic tags" + (is (= (str (html [:div])) "")) + (is (= (str (html ["div"])) "")) + (is (= (str (html ['div])) ""))) + (testing "tag syntax sugar" + (is (= (str (html [:div#foo])) "")) + (is (= (str (html [:div.foo])) "")) + (is (= (str (html [:div.foo (str "bar" "baz")])) + "a
b
"))) + (testing "vecs don't expand - error if vec doesn't have tag name" + (is (thrown? clojure.lang.ExceptionInfo + (html (vector [:p "a"] [:p "b"]))))) + (testing "tags can contain tags" + (is (= (str (html [:div [:p]])) "