 
 (defn escape-html
   "Change special characters into HTML character entities."
-  [^String text]
-  (.. ^String text
+  ^String [^String text]
+  (.. text
     (replace "&"  "&amp;")
     (replace "<"  "&lt;")
     (replace ">"  "&gt;")

                           :default
                             [(first matches) (rest matches)])]
    [tag-name
     (first (map strip-css (filter #(= \# (first %1)) names)))
     (vec (map strip-css (filter #(= \. (first %1)) names)))]))


(defn normalize-element

      (str/join " " cs))))


(defn render-attr! [name value sb]
  (let [name (to-str name)]
    (cond
      (true? value)    (append! sb " " name "=\"\"")
      (not value)      :nop
      (= "style" name) (let [style (render-style value)]
                         (when-not (str/blank? style)
                           (append! sb " style=\"" style "\"")))
      (= "class" name) (when-let [value (normalize-classes value)]
                         (append! sb " class=\"" value "\""))
      :else            (append! sb " " name "=\"" (to-str value) "\""))))


(defn render-attrs! [attrs sb]
  (doseq [[key value] attrs]
    (render-attr! key value sb)))


;;; render html


(defprotocol HtmlRenderer
  (-render-html [this parent *key sb]
    "Turn a Clojure data type into a string of HTML with react ids."))


(defn -render-element
  "Render an element vector as a HTML element."
  [element *key sb]
  (let [[tag attrs content] (normalize-element element)
        key                 @*key
        _                   (vswap! *key inc)
        attrs               (cond-> attrs
                              true       (dissoc :key)
                              (== key 1) (assoc  :data-reactroot "")
                              true       (assoc  :data-reactid key))
        inner-html          (:dangerouslysetinnerhtml attrs)
        attrs               (if inner-html
