|
8 | 8 | [garden.compiler :as gc] |
9 | 9 | [clojure.string :as str])) |
10 | 10 |
|
| 11 | +(def kebab-case-tags |
| 12 | + ;; from https://github.com/preactjs/preact-compat/issues/222 |
| 13 | + #{;; html |
| 14 | + "accept-charset" "http-equiv" |
| 15 | + ;; svg |
| 16 | + "accent-height" "alignment-baseline" "arabic-form" "baseline-shift" "cap-height" |
| 17 | + "clip-path" "clip-rule" "color-interpolation" "color-interpolation-filters" |
| 18 | + "color-profile" "color-rendering" "fill-opacity" "fill-rule" "flood-color" |
| 19 | + "flood-opacity" "font-family" "font-size" "font-size-adjust" "font-stretch" |
| 20 | + "font-style" "font-variant" "font-weight" "glyph-name" |
| 21 | + "glyph-orientation-horizontal" "glyph-orientation-vertical" "horiz-adv-x" |
| 22 | + "horiz-origin-x" "marker-end" "marker-mid" "marker-start" "overline-position" |
| 23 | + "overline-thickness" "panose-1" "paint-order" "stop-color" "stop-opacity" |
| 24 | + "strikethrough-position" "strikethrough-thickness" "stroke-dasharray" |
| 25 | + "stroke-dashoffset" "stroke-linecap" "stroke-linejoin" "stroke-miterlimit" |
| 26 | + "stroke-opacity" "stroke-width" "text-anchor" "text-decoration" "text-rendering" |
| 27 | + "underline-position" "underline-thickness" "unicode-bidi" "unicode-range" |
| 28 | + "units-per-em" "v-alphabetic" "v-hanging" "v-ideographic" "v-mathematical" |
| 29 | + "vert-adv-y" "vert-origin-x" "vert-origin-y" "word-spacing" "writing-mode" |
| 30 | + "x-height"}) |
| 31 | + |
11 | 32 | (def block-level-tag? |
12 | 33 | #{:head :body :meta :title :script :svg :iframe :style |
13 | 34 | :link :address :article :aside :blockquote :details |
|
17 | 38 | (defn- attr-map? [node-spec] |
18 | 39 | (and (map? node-spec) (not (keyword? (:tag node-spec))))) |
19 | 40 |
|
| 41 | +(defn- kebab-in-html? [attr-str] |
| 42 | + (or (contains? kebab-case-tags attr-str) |
| 43 | + (str/starts-with? attr-str "data-") |
| 44 | + (str/starts-with? attr-str "aria-") |
| 45 | + (str/starts-with? attr-str "hx-"))) |
| 46 | + |
| 47 | +(defn- kebab->camel [s] |
| 48 | + (str/replace s #"-(\w)" (fn [[_ match]] (str/capitalize match)))) |
| 49 | + |
| 50 | +(defn- camel->kebab [s] |
| 51 | + (str/replace s #"([A-Z])" (fn [[_ match]] (str "-" (str/lower-case match))))) |
| 52 | + |
| 53 | +(defn convert-attribute-reagent-logic |
| 54 | + [attr] |
| 55 | + (cond |
| 56 | + (string? attr) |
| 57 | + attr |
| 58 | + (keyword? attr) |
| 59 | + (if (kebab-in-html? (name attr)) |
| 60 | + (name attr) |
| 61 | + (kebab->camel (name attr))))) |
| 62 | + |
| 63 | +(defn convert-attribute-react-logic |
| 64 | + [attr-str] |
| 65 | + (let [kebab-str (camel->kebab attr-str)] |
| 66 | + ;; not using kebab-in-html? here because |
| 67 | + ;; React does not convert dataFoo to data-foo |
| 68 | + ;; but does convert fontStretch to font-stretch |
| 69 | + (if (kebab-case-tags kebab-str) |
| 70 | + kebab-str |
| 71 | + attr-str))) |
| 72 | + |
| 73 | +(defn convert-attribute [attr] |
| 74 | + (->> attr |
| 75 | + convert-attribute-reagent-logic |
| 76 | + convert-attribute-react-logic)) |
| 77 | + |
20 | 78 | (defn- nodify [node-spec {:keys [newlines?] :as opts}] |
21 | 79 | (cond |
22 | 80 | (string? node-spec) node-spec |
|
43 | 101 | (into {} (filter val m)) |
44 | 102 | {}) |
45 | 103 | :content (enlive/flatmap #(nodify % opts) (if (attr-map? m) ms more))} |
| 104 | + node (update node :attrs |
| 105 | + (fn [attrs] |
| 106 | + (->> attrs |
| 107 | + (map (fn [[k v]] |
| 108 | + [(convert-attribute k) v])) |
| 109 | + (into {})))) |
46 | 110 | node (if id (assoc-in node [:attrs :id] id) node) |
47 | 111 | node (if (seq classes) |
48 | 112 | (update-in node |
|
51 | 115 | (concat classes (if (string? kls) [kls] kls)))) |
52 | 116 | node)] |
53 | 117 | (cond-> node |
54 | | - (map? (get-in node [:attrs :style])) |
55 | | - (update-in [:attrs :style] (fn [style] |
56 | | - (-> (gc/compile-css [:& style]) |
57 | | - (str/replace #"^\s*\{|\}\s*$" "") |
58 | | - str/trim))) |
59 | | - (sequential? (get-in node [:attrs :class])) |
60 | | - (update-in [:attrs :class] #(str/join " " %)) |
| 118 | + (map? (get-in node [:attrs "style"])) |
| 119 | + (update-in [:attrs "style"] (fn [style] |
| 120 | + (-> (gc/compile-css [:& style]) |
| 121 | + (str/replace #"^\s*\{|\}\s*$" "") |
| 122 | + str/trim))) |
| 123 | + (sequential? (get-in node [:attrs "class"])) |
| 124 | + (update-in [:attrs "class"] #(str/join " " %)) |
61 | 125 | (and newlines? (block-level-tag? tag)) |
62 | 126 | (->> (list "\n")))) |
63 | 127 |
|
|
0 commit comments