None of this is working very well; bit it is working a bit.
This commit is contained in:
parent
3551623374
commit
357d4c5853
7 changed files with 2518 additions and 2 deletions
103
resources/cljs/hiccups/runtime.cljs
Normal file
103
resources/cljs/hiccups/runtime.cljs
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
(ns hiccups.runtime
|
||||
(:require [clojure.string :as cstring]))
|
||||
|
||||
;; this is copied/adapted from https://github.com/teropa/hiccups/tree/master
|
||||
;; basically to see how hard it is to get mainstream CLJS libraries running
|
||||
;; in Scittle.
|
||||
;;
|
||||
;; Copyright Tero Parviainen, licence Eclipse Public License.
|
||||
|
||||
;; The original requires `[clojure.string :as cstring]`, which of course I
|
||||
;; can't do.
|
||||
|
||||
(def ^{:doc "Regular expression that parses a CSS-style id and class from a tag name." :private true}
|
||||
re-tag #"([^\s\.#]+)(?:#([^\s\.#]+))?(?:\.([^\s#]+))?")
|
||||
|
||||
(def ^{:doc "Characters to replace when escaping HTML" :private true}
|
||||
character-escapes {\& "&", \< "<", \> ">", \" """})
|
||||
|
||||
(def ^{:doc "A list of tags that need an explicit ending tag when rendered."}
|
||||
container-tags
|
||||
#{"a" "b" "body" "canvas" "dd" "div" "dl" "dt" "em" "fieldset" "form" "h1" "h2" "h3"
|
||||
"h4" "h5" "h6" "head" "html" "i" "iframe" "label" "li" "ol" "option" "pre"
|
||||
"script" "span" "strong" "style" "table" "textarea" "ul"})
|
||||
|
||||
(defn as-str [x]
|
||||
(if (or (keyword? x) (symbol? x))
|
||||
(name x)
|
||||
(str x)))
|
||||
|
||||
(def ^:dynamic *html-mode* :xml)
|
||||
|
||||
(defn- xml-mode? []
|
||||
(= *html-mode* :xml))
|
||||
|
||||
(defn in-mode [mode f]
|
||||
(binding [*html-mode* mode]
|
||||
(f)))
|
||||
|
||||
(defn escape-html
|
||||
"Change special characters into HTML character entities."
|
||||
[text]
|
||||
(-> (as-str text)
|
||||
(cstring/escape character-escapes)))
|
||||
|
||||
(def h escape-html) ; alias for escape-html
|
||||
|
||||
(defn end-tag []
|
||||
(if (xml-mode?) " />" ">"))
|
||||
|
||||
(defn xml-attribute
|
||||
([name value] (xml-attribute name value true))
|
||||
([name value escape?]
|
||||
(str " " (as-str name) "=\"" (if escape? (escape-html value) value) "\"")))
|
||||
|
||||
(declare render-attr-map)
|
||||
|
||||
(defn render-attribute [[name value]]
|
||||
(cond
|
||||
(true? value)
|
||||
(if (xml-mode?)
|
||||
(xml-attribute name name)
|
||||
(str " " (as-str name)))
|
||||
(not value)
|
||||
""
|
||||
:else
|
||||
(xml-attribute name (if (map? value) (render-attr-map value) value) false)))
|
||||
|
||||
(defn render-attr-map [attrs]
|
||||
(apply str
|
||||
(sort (map render-attribute attrs))))
|
||||
|
||||
(defn normalize-element
|
||||
"Ensure a tag vector is of the form [tag-name attrs content]."
|
||||
[[tag & content]]
|
||||
(when (not (or (keyword? tag) (symbol? tag) (string? tag)))
|
||||
(throw (str tag " is not a valid tag name")))
|
||||
(let [[_ tag id class] (re-matches re-tag (as-str tag))
|
||||
tag-attrs {:id id
|
||||
:class (if class (cstring/replace class "." " "))}
|
||||
map-attrs (first content)]
|
||||
(if (map? map-attrs)
|
||||
[tag (merge tag-attrs map-attrs) (next content)]
|
||||
[tag tag-attrs content])))
|
||||
|
||||
(declare render-html)
|
||||
|
||||
(defn render-element
|
||||
"Render a tag vector as a HTML element."
|
||||
[element]
|
||||
(let [[tag attrs content] (normalize-element element)]
|
||||
(if (or content (container-tags tag))
|
||||
(str "<" tag (render-attr-map attrs) ">"
|
||||
(render-html content)
|
||||
"</" tag ">")
|
||||
(str "<" tag (render-attr-map attrs) (end-tag)))))
|
||||
|
||||
(defn render-html
|
||||
"Turn a Clojure data type into a string of HTML."
|
||||
[x]
|
||||
(cond
|
||||
(vector? x) (render-element x)
|
||||
(seq? x) (apply str (map render-html x))
|
||||
:else (as-str x)))
|
||||
Loading…
Add table
Add a link
Reference in a new issue