add various clojurescript utility functions

This commit is contained in:
Gered 2016-06-13 12:16:05 -04:00
parent c2a0531f2d
commit 8d65b78703
4 changed files with 177 additions and 5 deletions

View file

@ -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"]}}})

View 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 %)))))

View 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)))))

View 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 " "))