-
Notifications
You must be signed in to change notification settings - Fork 0
/
dom.cljs
120 lines (102 loc) · 2.76 KB
/
dom.cljs
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 dgknght.app-lib.dom
(:refer-clojure :exclude [comment])
(:require [dgknght.app-lib.client-macros :refer-macros [with-retry]]
[goog.object :as obj]))
(defn body []
(.-body js/document))
(defn target
[event]
(.-target event))
(defn value
[elem]
(.-value elem))
(defn prevent-default
"Instruct the DOM event that the default behavior should be suppressed."
[e]
(.preventDefault e))
(defn bounding-client-rect
([elem] (bounding-client-rect elem {}))
([elem {:keys [as-clojure?]}]
(let [raw (.getBoundingClientRect elem)]
(if as-clojure?
{:x (.-x raw)
:y (.-y raw)
:width (.-width raw)
:height (.-height raw)
:top (.-top raw)
:bottom (.-bottom raw)
:left (.-left raw)
:right (.-right raw)}
raw))))
(def ^:private key-codes
{9 :tab
13 :enter
27 :escape
37 :left
38 :up
39 :right
40 :down})
(defn key-code
"Get a keyword representing the keycode of the DOM event"
[event]
(get-in key-codes [(.-keyCode event)]))
(defn tab?
"Return a boolean value indicating whether or not the event
represents a press of the tab key"
[event]
(= :tab (key-code event)))
(defn enter?
"Return a boolean value indicating whether or not the event
represents a press of the enter key"
[event]
(= :enter (key-code event)))
(defn ctrl-key?
"Return a boolean value indicating whether or not the event
indicates the control key was pressed"
[event]
(.-ctrlKey event))
(defn shift-key?
"Return a boolean value indicating whether or not the event
indicates the shift key was pressed"
[event]
(.-shiftKey event))
(defn checked?
[event]
(.-checked (target event)))
(defn set-focus
[id]
(with-retry
(.focus (.getElementById js/document id))))
(defn- resolve-elem
[id-or-elem]
(if (string? id-or-elem)
(.getElementById js/document id-or-elem)
id-or-elem))
(defn set-style
[id-or-elem k v]
(-> id-or-elem
resolve-elem
(obj/get "style")
(obj/set k v)))
(defn get-style
[id-or-elem k]
(-> id-or-elem
resolve-elem
(obj/get "style")
(obj/get k)))
(defn set-attribute
[elem a-name a-value]
(.setAttribute elem a-name a-value))
(defn debounce
"Accepts a function and returns a function that will execute the given
function after a delay (300 milliseconds unless otherwise specified) if
the function is not invoked again during the delay (in which case case
the timer starts again and the given fn invoked after the delay)."
[f & [timeout]]
(let [timeout-id (atom nil)]
(fn [& args]
(when-let [id @timeout-id]
(js/clearTimeout id))
(reset! timeout-id
(js/setTimeout #(apply f args)
(or timeout 300))))))