add various clojurescript utility functions
This commit is contained in:
parent
c2a0531f2d
commit
8d65b78703
21
project.clj
21
project.clj
|
@ -4,8 +4,19 @@
|
|||
:license {:name "MIT License"
|
||||
:url "http://opensource.org/licenses/MIT"}
|
||||
|
||||
:dependencies [[org.clojure/clojure "1.8.0"]
|
||||
[compojure "1.4.0" :scope "provided"]
|
||||
[ring/ring-core "1.4.0" :scope "provided"]
|
||||
[cheshire "5.5.0"]
|
||||
[prismatic/schema "1.0.4"]])
|
||||
:dependencies [[cheshire "5.5.0"]
|
||||
[prismatic/schema "1.0.4"]
|
||||
[cljs-ajax "0.5.5"]
|
||||
[secretary "1.2.3"]]
|
||||
|
||||
:plugins [[lein-cljsbuild "1.1.3"]]
|
||||
|
||||
:profiles {:provided
|
||||
{:dependencies [[org.clojure/clojure "1.8.0"]
|
||||
[org.clojure/clojurescript "1.8.51"]
|
||||
[compojure "1.4.0"]
|
||||
[ring/ring-core "1.4.0"]]}}
|
||||
|
||||
:cljsbuild {:builds
|
||||
{:main
|
||||
{:source-paths ["src"]}}})
|
||||
|
|
62
src/webtools/cljs/ajax.cljs
Normal file
62
src/webtools/cljs/ajax.cljs
Normal file
|
@ -0,0 +1,62 @@
|
|||
(ns webtools.cljs.ajax
|
||||
(:require
|
||||
[clojure.walk :refer [stringify-keys keywordize-keys]]
|
||||
[ajax.core :as ajax]
|
||||
[webtools.cljs.utils :refer [->url get-anti-forgery-token]]))
|
||||
|
||||
(defn add-headers!
|
||||
[headers]
|
||||
(let [headers (stringify-keys headers)
|
||||
interceptor (ajax/to-interceptor
|
||||
{:request #(assoc % :headers (merge (:headers %) headers))})]
|
||||
(swap! ajax/default-interceptors (partial cons interceptor))
|
||||
headers))
|
||||
|
||||
(defn add-csrf-header!
|
||||
[]
|
||||
(let [token (get-anti-forgery-token)]
|
||||
(if token (add-headers! {"X-CSRF-Token" token}))
|
||||
token))
|
||||
|
||||
(defn GET
|
||||
[url & {:keys [format params on-success on-error on-complete keywords? headers]}]
|
||||
(let [url (->url url)
|
||||
json? (or (= :json format)
|
||||
(nil? format))]
|
||||
(ajax/GET url
|
||||
(merge
|
||||
{:format (or format :json)}
|
||||
(if json? {:keywords? (or keywords? true)})
|
||||
(if params {:params params})
|
||||
(if headers {:headers (stringify-keys headers)})
|
||||
(if on-success {:handler on-success})
|
||||
(if on-error {:error-handler on-error})
|
||||
(if on-complete {:finally on-complete})
|
||||
))))
|
||||
|
||||
(defn POST
|
||||
[url & {:keys [format params body on-success on-error on-complete keywords? headers]}]
|
||||
(let [url (->url url)
|
||||
json? (or (= :json format)
|
||||
(nil? format))]
|
||||
(ajax/POST url
|
||||
(merge
|
||||
{:format (or format :json)}
|
||||
(if json? {:keywords? (or keywords? true)})
|
||||
(if params {:params params})
|
||||
(if body {:body body})
|
||||
(if headers {:headers (stringify-keys headers)})
|
||||
(if on-success {:handler on-success})
|
||||
(if on-error {:error-handler on-error})
|
||||
(if on-complete {:finally on-complete})))))
|
||||
|
||||
(defn fetch!
|
||||
[destination-atom url & {:keys [format params keywords? on-error headers transform]}]
|
||||
(let [transform (or transform identity)]
|
||||
(GET url
|
||||
:format format
|
||||
:params params
|
||||
:keywords? keywords?
|
||||
:on-error on-error
|
||||
:headers headers
|
||||
:on-success #(reset! destination-atom (transform %)))))
|
25
src/webtools/cljs/dom.cljs
Normal file
25
src/webtools/cljs/dom.cljs
Normal file
|
@ -0,0 +1,25 @@
|
|||
(ns webtools.cljs.dom)
|
||||
|
||||
(defn element-by-id
|
||||
[id]
|
||||
(.getElementById js/document id))
|
||||
|
||||
(defn select-all-elements
|
||||
[selector]
|
||||
(vec (.querySelectorAll js/document selector)))
|
||||
|
||||
(defn select-element
|
||||
[selector]
|
||||
(.querySelector js/document selector))
|
||||
|
||||
(defn get-metatag-content
|
||||
[metatag-name]
|
||||
(if-let [tag (select-element (str "meta[name='" metatag-name "']"))]
|
||||
(.-content tag)))
|
||||
|
||||
(defn has-class?
|
||||
[element class-name]
|
||||
(if (.-classList element)
|
||||
(.contains (.-classList element) class-name)
|
||||
(doto (js/RegExp. (str "(^| )" class-name "( |$)") "gi")
|
||||
(.test (.-className element)))))
|
74
src/webtools/cljs/utils.cljs
Normal file
74
src/webtools/cljs/utils.cljs
Normal file
|
@ -0,0 +1,74 @@
|
|||
(ns webtools.cljs.utils
|
||||
(:import
|
||||
goog.History)
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[clojure.walk :refer [keywordize-keys]]
|
||||
[goog.events :as events]
|
||||
[goog.history.EventType :as EventType]
|
||||
[secretary.core :as secretary]
|
||||
[webtools.cljs.dom :as dom]))
|
||||
|
||||
(defn- get-hidden-field-value
|
||||
[hidden-field-id]
|
||||
(if-let [hidden-field (dom/element-by-id hidden-field-id)]
|
||||
(.-value hidden-field)))
|
||||
|
||||
(defn get-anti-forgery-token
|
||||
[]
|
||||
; bunch of common names for this csrf token that i've seen used
|
||||
; ring's own anti-forgery middleware has a helper which outputs
|
||||
; an <input type="hidden"> with the id "__anti-forgery-token"
|
||||
(->> [(dom/get-metatag-content "anti-forgery-token")
|
||||
(dom/get-metatag-content "__anti-forgery-token")
|
||||
(dom/get-metatag-content "csrf-token")
|
||||
(get-hidden-field-value "anti-forgery-token")
|
||||
(get-hidden-field-value "__anti-forgery-token")
|
||||
(get-hidden-field-value "csrf-token")]
|
||||
(remove nil?)
|
||||
(first)))
|
||||
|
||||
(defn dev?
|
||||
[]
|
||||
(if (undefined? js/__isDev)
|
||||
false
|
||||
(boolean js/__isDev)))
|
||||
|
||||
(defn context-url
|
||||
[]
|
||||
(if (undefined? js/__context)
|
||||
""
|
||||
(str js/__context)))
|
||||
|
||||
(defn supports-websockets?
|
||||
[]
|
||||
(not (-> (dom/select-element "html")
|
||||
(dom/has-class? "no-websockets"))))
|
||||
|
||||
(defn old-ie?
|
||||
[]
|
||||
(-> (dom/select-element "html")
|
||||
(dom/has-class? "old-ie")))
|
||||
|
||||
(defn ->url
|
||||
[url]
|
||||
(-> (str (context-url) url)
|
||||
(string/replace #"(/+)" "/")))
|
||||
|
||||
(defn hook-browser-navigation!
|
||||
[]
|
||||
(doto (History.)
|
||||
(events/listen
|
||||
EventType/NAVIGATE
|
||||
(fn [event]
|
||||
(secretary/dispatch! (.-token event))))
|
||||
(.setEnabled true)))
|
||||
|
||||
(defn redirect!
|
||||
[secretary-url]
|
||||
(-> (.-location js/window)
|
||||
(set! secretary-url)))
|
||||
|
||||
(defn pprint-json
|
||||
[x]
|
||||
(.stringify js/JSON (clj->js x) nil " "))
|
Reference in a new issue