/
core.cljc
120 lines (105 loc) · 3.99 KB
/
core.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
(ns cljs-styles.core
(:require [clojure.set :as set]
[clojure.string :as str]))
(def prop-prefixes
{:ms "ms"
:webkit "Webkit"
:moz "Moz"
:o "O"})
(def val-prefixes
{:ms "-ms-"
:webkit "-webkit-"
:moz "-moz-"
:o "-o-"})
(def default-prefixes-to-use
#{:ms :webkit :moz :o})
(def prop-needing-prefix
{:alignContent #{:webkit}
:alignItems #{:webkit}
:alignSelf #{:webkit}
:animation #{:webkit :moz}
:animationDelay #{:webkit :moz}
:animationDirection #{:webkit :moz}
:animationDuration #{:webkit :moz}
:animationFillMode #{:webkit :moz}
:animationIterationCount #{:webkit :moz}
:animationName #{:webkit :moz}
:animationPlayState #{:webkit :moz}
:animationTimingFunction #{:webkit :moz}
:appearance #{:webkit :moz}
:backfaceVisibility #{:webkit :moz}
:backgroundClip #{:webkit}
:borderImage #{:webkit :moz :o}
:borderImageSlice #{:webkit :moz :o}
:boxShadow #{:webkit :moz :ms}
:boxSizing #{:webkit :moz}
:clipPath #{:webkit}
:columns #{:webkit :moz}
:filter #{:webkit}
:flex #{:webkit :ms}
:flexBasis #{:webkit :ms}
:flexDirection #{:webkit :ms}
:flexFlow #{:webkit :ms}
:flexGrow #{:webkit :ms}
:flexShrink #{:webkit :ms}
:flexWrap #{:webkit :ms}
:fontSmoothing #{:webkit :moz}
:justifyContent #{:webkit :moz}
:order #{:webkit :moz}
:perspective #{:webkit :moz}
:perspectiveOrigin #{:webkit :moz}
:transform #{:webkit :moz :ms}
:transformOrigin #{:webkit :moz :ms}
:transformOriginX #{:webkit :moz :ms}
:transformOriginY #{:webkit :moz :ms}
:transformOriginZ #{:webkit :moz :ms}
:transformStyle #{:webkit :moz :ms}
:transition #{:webkit :moz :ms}
:transitionDelay #{:webkit :moz :ms}
:transitionDuration #{:webkit :moz :ms}
:transitionProperty #{:webkit :moz :ms}
:transitionTimingFunction #{:webkit :moz :ms}
:userSelect #{:webkit :moz :ms}})
(defn to-word-regexp [s]
(re-pattern (str "\\b" s "\\b")))
(def needs-transition-transform-prefix?
#{:webkit :moz :ms})
(defn prefix-transition-value [prefix value]
(if (needs-transition-transform-prefix? prefix)
(str/replace value #"\btransform\b" (str (val-prefixes prefix) "transform"))
value))
(defn capitalize [s]
(str (str/capitalize (subs s 0 1))
(subs s 1)))
(defn prefix-style [prefix [prop value]]
[(keyword (str (prop-prefixes prefix)
(capitalize (name prop))))
(case prop
:transition (prefix-transition-value prefix value)
value)])
(defn warn [& ss]
(binding #?(:clj [*out* *err*]
:cljs [*print-fn* *print-err-fn*])
(println "WARNING:" (apply str ss))))
(defn maybe-prefix-style [style prefixes-to-use]
(when-not (nil? (second style))
(conj (when-let [prefixes (prop-needing-prefix (first style))]
(map #(prefix-style % style) (set/intersection prefixes prefixes-to-use)))
style)))
(defn prefix [styles & [prefixes-to-use]]
(->> styles
(mapcat #(maybe-prefix-style % (or prefixes-to-use default-prefixes-to-use)))
(into {})))
(defn camelize [s]
(let [[head & tail] (str/split s #"-")]
(str/join (conj (map str/capitalize tail) head))))
(defmacro styles [& ss]
(let [m (apply hash-map ss)]
(doseq [k (keys m)]
(when (-> k name (.indexOf "-") (>= 0))
(warn "Use camelCase for styles. Got `" k "` which should be `:" (camelize (name k)) "`.")))
(if (some prop-needing-prefix (keys m))
`(prefix ~m #{:webkit})
m)))
(defmacro defstyles [name & ss]
`(def ~name (styles ~@ss)))